# Selecting sublists of different length if at least one element of the sublist fulfills a criterion

I have the following list, containing sublists with 1,2 or 3 elements.

 list= {{10.7}, {10.5}, {9.83},{7.64}, {4.76}, {4.21,
5.64}, {3.75}, {3.4, 5.11}, {3.13, 4.76, 6.5},{7, 5, 3}}


I have to select sublists if at least one element of the sublist is between 5 and 8. I think it should work with Select[], but I can't figure it out, because the sublists have different lengths.

• Related: (916), (8650). Possibly useful: (9719) Mar 19, 2015 at 8:57

## 3 Answers

list = {{10.7}, {10.5}, {9.83}, {7.64}, {4.76}, {4.21, 5.64}, {3.75},
{3.4, 5.11}, {3.13, 4.76, 6.5}, {7, 5, 3}};
Select[list, Or @@ (5 <= # <= 8 & /@ #) &]
(* {{7.64}, {4.21, 5.64}, {3.4, 5.11}, {3.13, 4.76, 6.5}, {7, 5, 3}} *)


You get the same result using siblings of Select:

Pick[list, Or @@ (5 <= # <= 8 & /@ #) & /@ list]
Cases[list, _?(Or @@ (5 <= # <= 8 & /@ #) &)]


In Mathematica 10 you can use AnyTrue for this:

 list ~Select~ AnyTrue[5 <= # <= 8 &]

{{7.64}, {4.21, 5.64}, {3.4, 5.11}, {3.13, 4.76, 6.5}, {7, 5, 3}}


You can also use VectorQ and Not:

Select[list, ! VectorQ[#, 5 > # || # > 8 &] &]

{{7.64}, {4.21, 5.64}, {3.4, 5.11}, {3.13, 4.76, 6.5}, {7, 5, 3}}


If aiming for speed consider purely numeric operations. Assuming all positive numbers as in your example you could use:

Pick[list, UnitStep[Max /@ Clip[list, {5, 8}, {-1, -1}]], 1]

{{7.64}, {4.21, 5.64}, {3.4, 5.11}, {3.13, 4.76, 6.5}, {7, 5, 3}}


Timings:

list = RandomReal[{0, 200}, {50000, 50}];

Select[list, AnyTrue[5 <= # <= 8 &]]                         // Timing // First
Select[list, ! VectorQ[#, 5 > # || # > 8 &] &]               // Timing // First
Pick[list, UnitStep[Max /@ Clip[list, {5, 8}, {-1, -1}]], 1] // Timing // First

0.8736

1.5288

0.0156


Using another variant of Cases works, too:

Cases[list, {a___, x_, b___} /; 4 < x <= 5 -> {a, x, b}]
(* {{4.76}, {4.21, 5.64}, {3.13, 4.76, 6.5}, {7, 5, 3}} *)