# Filter real numbers that less than 1.0 in the whole list

Assuming we have a list below, it has real number elements and complex numbers, how can I quickly find if the list has any Real number that its value is less than 1.0?

 lis = {3 Sqrt[354], Sqrt[2962], Sqrt[2746], 3 Sqrt[282], Sqrt[2338],
Sqrt[2146], 3 Sqrt[218], Sqrt[1786], Sqrt[1618], 27 Sqrt[2], Sqrt[
1306], Sqrt[1162], 3 Sqrt[114], Sqrt[898], Sqrt[778], 3 Sqrt[74],
Sqrt[562], Sqrt[466], 3 Sqrt[42], Sqrt[298], Sqrt[226], 9 Sqrt[2],
Sqrt[106], Sqrt[58], 3 Sqrt[2], I Sqrt[14], I Sqrt[38], 3 I Sqrt[6],
I Sqrt[62], I Sqrt[62], 3 I Sqrt[6], I Sqrt[38], I Sqrt[14], Sqrt[
1.2], Sqrt[58], Sqrt[1.06], 9 Sqrt[2], Sqrt[226]}


I am also considering if we can find methods to filter any real or complex numbers with specific values in any types list (e.g. there are some string elements mixed with real and complex number elements in a given list). But this could be another question and isn't necessary for my example. Please leave some advice if you interested! Thanks in advance!

• I would numericize first, something like FreeQ[N @ lis, _Real?(LessThan[1])] Dec 21 '17 at 2:30
• One of the most straightforward: Select[lis, Re[#] < 1 && Im[#] == 0 &] Dec 21 '17 at 3:56

Pick[lis, InternalRealValuedNumericQ@# && # < 1 & /@ lis]


{}

Pick[lis, InternalRealValuedNumericQ @ # && # < 5 & /@ lis]


{3 Sqrt[2], 1.09545, 1.02956}

Pick combined with @aardvark2012's selector approach and exploiting the fact that Negative, Positive, NonPositive ... are Listable:

Pick[lis, NonPositive[lis - 5]]


{3 Sqrt[2], 1.09545, 1.02956}

This seems to be the fastest of methods posted so far.

• +1. I wonder how many "How do I select elements satisfying condition $P$?" questions the site has, all with virtually the same large set of alternatives. BTW, I was going to use DeveloperRealQ /@ N@lis, but then thought better of it for some reason Dec 21 '17 at 3:35
• @MichaelE2, thank you for the upvote. I agree re the number of questions with answers using Pick/Select/Cases... . FWIW, this one is more about specifying the condition/selector to get Reals.
– kglr
Dec 21 '17 at 3:42
• Something like Re[x] < 1 && Im[x] == 0, in some form or other, seems a kinda straightforward, first-guess sort of thing to try to me (almost Nasser's). Dec 21 '17 at 3:53
• Thank you! Very helpful! Dec 21 '17 at 15:39

how can I quickly find if the list has any Real number that its value is less than 1.0?

One way might be

Cases[ReIm[lis],{x_,y_}/;y==0&&x<1]
(*{} *)


Example

 lis={.7, .7I .7+1, 2, 2I, 2+1 I};
Cases[ReIm[lis],{x_,y_}/;y==0&&x<1 :> Complex[x,y]]


Using the above, you can now add any kind of checks on x and y to filter any kind of number you want. For example, to look for pure complex numbers:

 Cases[ReIm[lis],{x_,y_}/;x==0&&y!=0 :> Complex[x,y]]


To look for number with real and complex parts

  Cases[ReIm[lis],{x_,y_}/;x!=0&& y!=0 :> Complex[x,y]]


And so on.

Here's a way using Pick:

Pick[lis, UnitStep[1 - Re@#] + I*Im@# &@N@lis, 1]
(*  {}  *)

lis2 = lis/10;
Pick[lis2, UnitStep[1 - Re@#] + I*Im@# &@N@lis2, 1]
(*  {Sqrt[29/2]/5, 3/(5 Sqrt[2]), 0.109545, Sqrt[29/2]/5, 0.102956}  *)


UnitStep[1 - Re@#] returns 1 if the real part of the number is less than 1. And I*Im@# is 0 if the number is real; otherwise, it will have a nonzero imaginary part and be a number of type Complex.

You may use Selectand Element.

Select[# ∈ Reals && # < 1 &]@lis

{}


There appear to be no items that are both in the reals and less than one.

If you do not need the items but only the result of the test then you could place in an If and test the Length.

If[
Length@Select[# ∈ Reals && # < 1 &]@lis > 0,
True,
False]

False


Hope this helps.

There's always Select:

Select[lis, Negative[# - 1] &]


Negative is nice because it'll work on pretty much anything, but only return True if the argument is a negative real number. Testing it on a longer list:

SeedRandom[123456]
lis = RandomSample[
Join[RandomReal[2, 10], RandomComplex[{-1 - I, 1 + I}, 10]],
20];

Select[lis, Negative[# - 1] &]

(* {0.982588, 0.86323, 0.0961836, 0.963281, 0.780961, 0.225647, 0.34709} *)


But the question is a little ambiguous -- the phrase "how can I quickly find if the list has any Real number that its value is less than 1.0?" indicates that you don't actually care what the numbers are, just whether they're there or not. If that's what you're really after, you can do:

CountsBy[lis, Negative[# - 1] &][True]

(* 7 *)


As far as generalization goes, Select is so incredibly generalizable that it's hard to know where to start. If, say, there are strings involved in your list, these approaches still work as they are:

SeedRandom[123456]
lis = RandomSample[
Join[RandomReal[2, 10], RandomComplex[{-1 - I, 1 + I}, 10],
RandomChoice[CharacterRange["a", "z"], 10]], 30]

Select[lis, Negative[# - 1] &]
CountsBy[lis, Negative[# - 1] &][True]

(* {0.0961836, 0.982588, 0.225647, 0.780961, 0.963281}
5 *)
`