# Count and positions of an element in a given list

I want to implement an operation on the following list:

For a given arbitrary length of list $$\{a1,a2,a3,a4,a5,a6,a7,a8,\cdots\}$$, the task is to find the number of zeros and their position(s). So I want my output to be:

{number of zeros, {position(s) of zero(s)}

For example, $$\{0,1,2,-1,0,1,3,0\}$$, I want to count $$0$$; so zero happens twice and the position of zero to be in 1st, 5th, 8th position, i.e., I want my output as $$\{3, \{1, 5 ,8\}\}$$.

First of all, I know how to count the zeros:

  list1={0,1,2,-1,0,1,3,0};
Count[list1, x_ /; x == 0]


Then it gives 3 as an output. Maybe I can find the position(s) by using the loop explicitly, but I think there is a simpler way to implement it in Mathematica.

• {Length@#, Flatten@#} &@Position[list1 = {0, 1, 2, -1, 0, 1, 3, 0}, 0]
– Alan
Commented May 4, 2023 at 12:08

For integer lists:

{Length @ #, #} & @  RandomPrivatePositionsOf[list1, 0]

{3, {1, 5, 8}}


This is much faster than alternatives for long lists with relatively few zeros.

zeros[ll_] := {Length[#], #} &@Flatten@Position[ll, 0]


or

zeros[ll_] := {Count[ll, 0], Flatten@Position[ll, 0]}


Using PositionIndex:

Clear["Global*"];
list1 = {0, 1, 2, -1, 0, 1, 3, 0};

cpi[k_List,
el_] := {Count[#, el],
If[MissingQ@PositionIndex[#][el], {}, PositionIndex[#][el]]} &@k

cpi[list1, #] & /@ Range[0, 4]


Other variations:

Through[{Count[0], Flatten@*Position[0]}[list1]]

{Length@#, #} &@PositionIndex[list1][0]


{{3, {1, 5, 8}}, {2, {2, 6}}, {1, {3}}, {1, {7}}, {0, {}}}

list = {0, 1, 2, -1, 0, 1, 3, 0};


Using Query

Join @@@ Query[{Count[0], Position[0]}] @ list


{3, {1, 5, 8}}

Using Comap (new in 14.0)

Join @@@ Comap[{Count[0], Position[0]}] @ list


{3, {1, 5, 8}}

list1 = {0, 1, 2, -1, 0, 1, 3, 0};


Using MapIndexed and the third argument of GroupBy:

GroupBy[MapIndexed[{#2, #1} &, list1, {-1}],
Last, {Length@#2, Splice /@ #1} & @@ Thread@# &][0]


{3, {1, 5, 8}}

Or using Replace:

Block[{n = 0}, Last@Replace[list1,
y_ /; y == 0 :> {++n, Flatten@Position[list1, y]}, {-1}]]


{3, {1, 5, 8}}`