# What is the inverse of the Position function?

What is the inverse of the Position?

I have an array which contains the positions of elements and I want a function which returns an List which contains 1 where those elements are and 0 elsewhere. For example, the List {1, 5} would return {1,0,0,0,1} or {2,1,4} would return {1,1,0,1}. Additional arguments might need to be supplied for length etc. (Technically, this function is a inverse of restricted version of the Position function)

I realize that I could do with Table but it seems like this would be a common enough process that there would be a built in function for this. However, I have not been able to find it in the documentation.

• Am I missing something? Reverse[IntegerDigits[Tr[2^(#-1)],2]]& s/b quite efficient. Add the length argument to IntegerDigits if you want a mask matching some arbitrary length.
– ciao
Sep 4, 2017 at 1:26
• I would not call that the inverse of Position ... the true inverse of Position, i.e. a function that takes Position's output and returns its input, is Extract Sep 5, 2017 at 12:34

I don't know that you can do it in a single command. But it's easy enough to do in two. Say your list is list={2,1,4};

x = ConstantArray[0, Max[list]];
x[[list]] = 1;

x
{1, 1, 0, 1}


Effectively, Part (or the shortcut [[ ]]) acts as an approximate inverse of Position.

• Accepting this answer because it is the fastest in my limited testing Sep 5, 2017 at 14:00
• @TheSquareCow This solution is silent about duplicates. (Also, it is hard to believe it is fastest. Can you post your tests?)
– Alan
Sep 5, 2017 at 15:35
• Yes, I would throw DeleteDuplicates at the list first before moving on. Sep 5, 2017 at 15:54
• Here are my tests: In:= RepeatedTiming[(x = ConstantArray[0,Max[#]]; x[[#]] = 1; x)&[{2,1,4}], 20] Out= {6.5*10^-6,{1,1,0,1}} In:= RepeatedTiming[(Normal@SparseArray[Thread[#->1]])&[{2,1,4}], 20] Out= {0.00002,{1,1,0,1}} In:= RepeatedTiming[(Rest@BinCounts[#])&[{2,1,4}], 20] Out= {0.00032,{1,1,0,1}} In:= RepeatedTiming[Reverse[IntegerDigits[Tr[2^(#-1)],2]]&[{2,1,4}], 20] Out= {0.00001,{1,1,0,1}} Sep 6, 2017 at 16:00
• Sorry about the formatting, I couldn't get the newlines inside a comment box to work correctly. Sep 6, 2017 at 16:02
Normal@SparseArray[Thread[{1, 5} -> 1]]
(*  {1, 0, 0, 0, 1}  *)

(*  {1, 1, 0, 1}  *)

list = {2, 1, 5};


or

dat = ConstantArray[0, Max@list];
dat[[{2, 1, 5}]] = 1;
dat

In:= Rest@BinCounts[{1, 5}]

Out= {1, 0, 0, 0, 1}

In:= Rest@BinCounts[{2, 1, 4}]

Out= {1, 1, 0, 1}


With ReplaceAt (since V 13.1)

list = {1, 5};

ReplaceAt[Table[0, Max @ list], _ :> 1, List /@ list]


{1, 0, 0, 0, 1}

With ReplacePart

list = {1, 2, 3, 6};

ReplacePart[Table[0, Max @ list], Thread[list -> 1]]


{1, 1, 1, 0, 0, 1}

ClearAll[f]
f = x |-> Array[Boole @ MemberQ[#] @ x &, Max @ x];


Examples:

{#, f @ #} & /@ {{2, 1, 5}, {2, 1, 2, 4}, {1, 5}}

position f @ position
{2, 1, 5} {1, 1, 0, 0, 1}
{2, 1, 2, 4} {1, 1, 0, 1}
{1, 5} {1, 0, 0, 0, 1}
f[pos_List] :=
MapAt[# + 1 &, ConstantArray[0, Max[pos]], List /@ Union@pos]


or

g[pos_List] := Module[{temp = Max[pos] - # & /@ Union@pos},
2^temp // Total // IntegerDigits[#, 2] &
]


Usage:

testcases = {{2, 1, 5}, {2, 1, 2, 4}, {1, 5}}

f /@ testcases
g /@ testcases


Result:

{{1, 1, 0, 0, 1}, {1, 1, 0, 1}, {1, 0, 0, 0, 1}}

Using ReplaceAll:

f = Range@Max[#] /. Catenate[Thread /@ {Complement[Range@Max[#], #] -> 0, # -> 1}] &;

f@{1, 5}

(*{1, 0, 0, 0, 1}*)

f@{2, 1, 4}

(*{1, 1, 0, 1}*)