And[f[1],f[2]]
doesn't evaluate f[2]
if f[1]
is false, but And@@{f[1],f[2]}
does.
How do I evaluate And@@(f/@list)
, or Or@@(f/@list)
for that matter, without evaluating more than necessary of f/@list
?
Mathematica Stack Exchange is a question and answer site for users of Wolfram Mathematica. It only takes a minute to sign up.
Sign up to join this communityAnd[f[1],f[2]]
doesn't evaluate f[2]
if f[1]
is false, but And@@{f[1],f[2]}
does.
How do I evaluate And@@(f/@list)
, or Or@@(f/@list)
for that matter, without evaluating more than necessary of f/@list
?
How about using Block
?:
f[a_] := a < 2
lst = Range[5]
Block[{f}, And @@ f /@ lst]
If you already have the explicit list at hand, you can simply use Unevaluated
:
And @@ Unevaluated @ {f[1], f[2], f[3], f[4], f[5]}
If you don't even want to generate the expression And[f[1], f[2], …]
in intermediate step, then I think it's better to avoid And
:
Catch[If[! f @ #, Throw @ False] & /@ lst; True]
Similarly, Or @@ f /@ lst
can be implemented as
Catch[If[f @ #, Throw @ True] & /@ lst; False]
For completeness, as mentioned by ilian and Blrp, AllTrue
and AnyTrue
seems to be the best choice since v10.0.
A simple test for all the methods under this question:
f[a_] := a < 250000
f2 = # < 250000 &;
lst = Range[500000];
Block[{f}, And @@ f /@ lst] // RepeatedTiming
(* {0.29, False} *)
Block[{f}, And @@ f2 /@ lst] // RepeatedTiming
(* {0.290, False} *)
Catch[If[! f @ #, Throw @ False] & /@ lst; True] // RepeatedTiming
(* {0.488, False} *)
Catch[If[! f2@ #, Throw @ False] & /@ lst; True] // RepeatedTiming
(* {0.4785, False} *)
Catch[Scan[If[! f @ #, Throw @ False] &, lst]; True] // RepeatedTiming
(* {0.3554, False} *)
Catch[Scan[If[! f2 @ #, Throw @ False] &, lst]; True] // RepeatedTiming
(* {0.352, False} *)
And @@ f /@ Hold @@ lst // RepeatedTiming
(* {0.231, False} *)
And @@ f2 /@ Hold @@ lst // RepeatedTiming
(* {0.194, False} *)
AllTrue[lst,f] // RepeatedTiming
(* {0.165, False} *)
AllTrue[lst,f2] // RepeatedTiming
(* {0.13, False} *)
Tested on v12.1.0. (Wolfram cloud, Android app. )
AllTrue
is another way, and most convenient in some circumstances such as built-in functions and unassigned pure functions. Add it, as well as AnyTrue
, and I'll accept.
$\endgroup$
– Blrp
Mar 15 '20 at 22:32
Ctach[Map[...]]
construct, use Scan
instead of Map
as it doesn't generate the intermediate List
like Map
.
$\endgroup$
– rcollyer
Mar 16 '20 at 12:57
Map
just for compactness, and didn't expect the generation of output slows down the code that much. Edited. Thx for the reminding.
$\endgroup$
– xzczd
Mar 17 '20 at 2:01
AllTrue[list, f]
? $\endgroup$ – ilian Mar 15 '20 at 14:39AllTrue
is cleaner, but for reference:And @@ f /@ Hold @@ list
$\endgroup$ – Mr.Wizard Mar 16 '20 at 2:38