Efficient way to test if all the elements in a list are Integers?
s = {1,2,3,3,5,6,3};
I would write:
And @@ (IntegerQ /@ s)
EDIT
With V10 we can use:
AllTrue[s, IntegerQ]
True
NoneTrue[s // N, IntegerQ]
True
VectorQ
is the best way I know. Here are three types of input, packed array of Integer
, an (non-packed) array of Integer
, and an array of not all Integer
.
packed = RandomInteger[10, 10^7];
unpacked = Flatten@ConstantArray[{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, 10^6];
nonint = ReplacePart[packed, 10^6 -> 1.5];
Developer`PackedArrayQ@unpacked
(* False *)
Testing VectorQ[list, IntegerQ]
:
VectorQ[packed, IntegerQ]
VectorQ[unpacked, IntegerQ]
VectorQ[nonint, IntegerQ]
(*
True
True
False
*)
Comparing the timings with two other methods (the timing function timeAvg
is given below):
VectorQ[packed, IntegerQ] // timeAvg
VectorQ[unpacked, IntegerQ] // timeAvg
VectorQ[nonint, IntegerQ] // timeAvg
(*
2.64695*10^-7
0.0319406
0.00318189
*)
MatchQ[packed, {___Integer}] // timeAvg
MatchQ[unpacked, {___Integer}] // timeAvg
MatchQ[nonint, {___Integer}] // timeAvg
(*
9.5835*10^-7
0.157701
0.065558
*)
And @@ (IntegerQ /@ packed) // timeAvg
And @@ (IntegerQ /@ unpacked) // timeAvg
And @@ (IntegerQ /@ nonint) // timeAvg
(*
2.782322
2.858287
2.540433
*)
You may note that on packed arrays VectorQ
and MatchQ
take virtually no time. In fact, it's the same amount of time no matter what the size. This is because a packed array is a special efficient internal representation of an array. In particular it has to be an array of all the same type of number (only Integer
, Real
, and Complex
are allowed). So checking the type is easy. See What is a Mathematica packed array?
The site-standard timeAvg
function:
SetAttributes[timeAvg, HoldFirst]
timeAvg[func_] :=
Do[If[# > 0.3, Return[#/5^i]] & @@
AbsoluteTiming@Do[func, {5^i}], {i, 0, 15}];
Use Map
, abbreviated /@
. For example:
lis = {4, 5/2, 3., 6/3, Pi};
IntegerQ /@ lis (* or Map[IntegerQ, lis] *)
(* {True, False, False, True, False} *)