# How to count elements of lists within lists

If I have some list of lists of coordinates, i.e.

list={{{0,1},{1,2},{2,3},{3,4}},{{3,2},{2,3},{1,4},{0,5}},{{3,1},{2,2},{2,4},{3,5}}}


how can I count how many of the y coordinates in each of the lists has a value of 2 or greater? E.g. the first list has 3 y coordinates greater than or equal to 2, the second has 4 and the third has 3. I have tried

list1=list[[All, All, 2]]
Count[Map[list1], u_ /; u > 2]


but this isn't correctly separating my data by list.

• Try this: Count[#, x_ /; x[[2]] >= 2, 1] & /@ list. Commented Mar 15, 2018 at 15:44
• That's great thanks!
– JJH
Commented Mar 15, 2018 at 15:52

Here's one way:

Total[UnitStep[list[[All,All,2]]-2],{2}]


{3, 4, 3}

Here is another version using Count (another one is given in a comment):

Count[{_, _?(GreaterEqualThan[2])}] /@ list


And another one that I also like:

Count[{_, y_ /; y >= 2}] /@ list


Putting the condition close to the variable makes it clear what is happening.

Length@*Select[# >= 2 &] /@ list[[All, All, 2]]

Map[Length@*Select[# >= 2 &]][list[[All, All, 2]]] (* as operator form *)

CountsBy[# >= 2 &] /@ list[[All, All, 2]] // KeyDrop[False] //
Values // Flatten

Map[CountsBy[Last@# >= 2 &], list] // KeyDrop[False] //
Values // Flatten

Map[Last, list, {2}] // Map[Select[# >= 2 &]] // Map[Length] (* readable *)

list /. {a_?NumberQ, b_?NumberQ} :> b //
DeleteCases[#, _?(# < 2 &), 2] & // Map[Length]

(Scan[If[Last@# >= 2, Sow[Last@#], Nothing] &, #] // Reap // Last //
First // Length) & /@ list


Result

{3, 4, 3}

Length /@ Replace[list, x_ /; Last[x] < 2 :> Nothing, {2}]


{3, 4, 3}

In a shorter way, using Cases:

Map[Length@Cases[#, {_, y_} /; y >= 2] &]@list
(*Thanks, Eldo!*)

(*{3, 4, 3}*)


Also, an alternative using GroupBy:

Map[Length]@Keys@GroupBy[list, Map[If[#[[2]] >= 2, #[[2]], Nothing] &]]

(*{3, 4, 3}*)

• +1 - You can further shorten it since the Level specification is redundant: Length@Cases[#, {_, y_} /; y >= 2] & /@ list
– eldo
Commented Sep 17, 2023 at 17:21
• Thanks for pointing out that important detail, @eldo! :-) Commented Sep 17, 2023 at 17:33

You can use Query with GreaterEqualThan.

With list as in OP

Query[
Map[Length]
, Select[GreaterEqualThan[2]@*Last]
]@list

{3, 4, 3}


Hope this helps.

Length@Select[#, #[[2]] >= 2 &] & /@ list
$$$$
`