37
$\begingroup$

In Python, there is a function all which returns true if all of its arguments are true, and any which returns true if at least one of its arguments is true. I find these quite useful in functional programming. Given how much Mathematica encourages functional programming constructs, I was surprised not to find anything equivalent to these all and any functions in the documentation. Does Mathematica have equivalents to these functions, or some standard way to achieve the same effect?

I can implement them myself as

AllOf[b_List] := Fold[And, True, b][[1]]
AllOf[b__] := Fold[And, True, {b}][[1]]

AnyOf[b_List] := Fold[Or, True, b][[1]]
AnyOf[b__] := Fold[Or, True, {b}][[1]]

(these may not be always correct, but they've worked for my purposes). But I would rather use something built-in if it exists.

$\endgroup$
3

7 Answers 7

40
$\begingroup$

Both, And and Or should work for All and Any respectively. You may have to get creative in how you apply them, though. For instance,

And @@ {True, False, True}

works just like you would expect

AllOf @ {True, False, True}

to without any additional work. Similarly,

Or @@ {False, True, False}

works like AnyOf.

$\endgroup$
4
  • $\begingroup$ Huh, somehow I missed that And and Or can apply to multiple (>2) arguments. $\endgroup$
    – David Z
    Commented Jan 29, 2012 at 4:21
  • 6
    $\begingroup$ It's interesting to mention that they are also short circuiting and have HoldAll. So False && expr will never evaluate expr. $\endgroup$
    – Szabolcs
    Commented Jan 29, 2012 at 9:07
  • $\begingroup$ @Szabolcs See my answer to this question: stackoverflow.com/questions/4911827/…, for a short-circuiting implementation. I also discuss short-curcuiting here: stackoverflow.com/questions/4867076/… $\endgroup$ Commented Jan 29, 2012 at 10:20
  • 2
    $\begingroup$ If you want to benefit from short circuiting, while applying And to a List like in this answer, note that you have to use Unevaluated, i.e. Apply[And, Unevaluated[{False, expr}]] $\endgroup$ Commented Apr 23, 2014 at 8:58
27
$\begingroup$

You can implement equivalents of the any and all functions in MATLAB and python in Mathematica using the MemberQ and FreeQ functions as:

any[x_List] := MemberQ[x, True]
all[x_List] := FreeQ[x, False]

For large lists, these will be about an order of magnitude faster in the worst case to several orders faster in the best case, when compared to the And and Or solutions.

$\endgroup$
2
  • 2
    $\begingroup$ +1. I suspect that the speed advantage comes largely from the fact that in your functions, the clauses have been already evaluated, while And and Or evaluate them only if necessary. If you add the time it took to evaluate those, the difference might be not as large. OTOH, if, for a particular problem, you have some fast vectorized way to obtain the list of True/False, this may indeed be much faster than using And / Or. $\endgroup$ Commented Jan 29, 2012 at 21:53
  • 1
    $\begingroup$ This is really "lateral thinking" :). I always use MemberQ and FreeQ the other way around (ie using the "element" as the free var) $\endgroup$ Commented Jul 24, 2012 at 5:21
19
$\begingroup$

The Wolfram Language and Mathematica 10 (available now on the Raspberry Pi) have new functions — AnyTrue, AllTrue, NoneTrue — which take a predicate and test any/all/none on the input list. For example:

AnyTrue[Range@5, EvenQ]
(* True *)

AllTrue[{True, False, False}, TrueQ] (* or Identity in place of TrueQ *)
(* False *)

These functions can also be turned into a predicate themselves by using just a test function as a single argument:

NoneTrue[StringQ]@{"a", 1, 23}
(* False *)
$\endgroup$
2
  • $\begingroup$ The latter one could use Identity in place of TrueQ, provided all elements are True or False. The AllTrue[EvenQ][{2, 4, 6}] syntax is interesting to show too. $\endgroup$
    – Szabolcs
    Commented Mar 29, 2014 at 17:23
  • $\begingroup$ Yes, I'll add that syntax in as well. $\endgroup$
    – rm -rf
    Commented Mar 29, 2014 at 17:30
16
$\begingroup$

In addition to the simple form where you already have a list of True|False elements, you may want lazy evaluation in creating that list, short circuiting if the test fails. You can do this with Hold. I include a Print statement so that you can see what actually evaluates:

(Print@#; # != 0) & /@ Hold[1, 0, 0, 1, 1, 0, 1, 0]
And @@ %

(Print@#; # != 0) & /@ Hold[0, 0, 1, 1, 0, 1, 0]
Or @@ %

Another form that can come in handy if you have a function that uses two arguments is Inner:

a = {91, 95, 72, 90, 82, 97, 76, 81, 82, 70};
b = {7, 4, 3, 9, 1, 4, 5, 6, 5, 2};

Inner[(Print[##]; Divisible[##]) &, a, b, And]

Inner[(Print[##]; Divisible[##]) &, a, b, Or]
$\endgroup$
13
$\begingroup$

Another way for All is to use VectorQ function

VectorQ[lis, TrueQ]
$\endgroup$
4
$\begingroup$

Using ContainsOnly and ContainsAny (new in 10.2)

AllOf[b_] := ContainsOnly[b, {True}]

AnyOf[b_] := ContainsAny[b, {True}]

 AnyOf /@ {{True, False}, {False, False}}

{True, False}

AllOf /@ {{True, True}, {True, False}}

{True, False}

$\endgroup$
1
$\begingroup$

No one gives a summary of explicit timing. Here is one

First, define

ClearAll[timing]
timing[a_] := {
   Prepend[And @@ a; // RepeatedTiming, "And@@a"],
   Prepend[FreeQ[a, False]; // RepeatedTiming, "FreeQ[a,False]"], 
   Prepend[MemberQ[a, False]; // RepeatedTiming, "MemberQ[a,False]"], 
   Prepend[VectorQ[a, TrueQ]; // RepeatedTiming, "VectorQ[a,TrueQ]"], 
   Prepend[AllTrue[a, TrueQ]; // RepeatedTiming, "AllTrue[a,TrueQ]"], 
   Prepend[AnyTrue[a, TrueQ]; // RepeatedTiming, 
    "AnyTrue[a,TrueQ]"]} // TableForm

Even random True and False mixed List

a = RandomChoice[{True, False}, 10^6];
timing[a]

gives

7.05217*10^-6   Null    And@@a
3.86491*10^-7   Null    FreeQ[a,False]
3.76835*10^-7   Null    MemberQ[a,False]
2.95758*10^-7   Null    VectorQ[a,TrueQ]
2.88454*10^-7   Null    AllTrue[a,TrueQ]
3.70405*10^-7   Null    AnyTrue[a,TrueQ]

All True List

a = RandomChoice[{True}, 10^6];
timing[a]

gives

0.0139276   Null    And@@a
3.06406*10^-7   Null    FreeQ[a,False]
3.06094*10^-7   Null    MemberQ[a,False]
0.0774998   Null    VectorQ[a,TrueQ]
0.0791204   Null    AllTrue[a,TrueQ]
2.84386*10^-7   Null    AnyTrue[a,TrueQ]

All False List

a = RandomChoice[{False}, 10^6];
timing[a]

gives

0.0085237   Null    And@@a
4.08738*10^-7   Null    FreeQ[a,False]
4.20621*10^-7   Null    MemberQ[a,False]
3.25424*10^-7   Null    VectorQ[a,TrueQ]
3.15501*10^-7   Null    AllTrue[a,TrueQ]
0.0902116   Null    AnyTrue[a,TrueQ]

It seems FreeQ and MemberQ are best

But VectorQ is good for packed array

s = ConstantArray[1, 1000000];
FreeQ[IntegerQ /@ s, True]; // RepeatedTiming
VectorQ[s, IntegerQ]; // RepeatedTiming
s = Developer`FromPackedArray@ConstantArray[1, 1000000];
FreeQ[IntegerQ /@ s, True]; // RepeatedTiming
VectorQ[s, IntegerQ]; // RepeatedTiming

gives

{0.111584, Null}
{1.91957*10^-7, Null}
{0.107412, Null}
{0.00319087, Null}
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.