# Applying And to lists of Booleans

I'd like to take {True,True,False} and {True,False,False} and apply And to get {True,False,False}. Right now I'm using

And @@ # & /@ Transpose[{{True, True, False}, {True, False, False}}]


Is that really the best way? I would like And[{True, True, False}, {True, False, False}] to work but it does not.

• +1 Nice question, invites many possible responses. Commented Sep 4, 2012 at 16:51
• Related: (3217) Commented Jan 18, 2015 at 15:30

I like more :

MapThread[ And, {{True, True, False}, {True, False, False}}]

{True, False, False}


Edit

We should test efficiency of various methods for a few different lists.

Definitions

Argento[l_] := (And @@ # & /@ Transpose[l]; // AbsoluteTiming // First)
Brett[l_]   := (And @@@ Transpose[l]; // AbsoluteTiming // First)
Artes[l_]   := (MapThread[And, l]; // AbsoluteTiming // First)
kguler[l_]  := (And[l[[1]], l[[2]]] // Thread; // AbsoluteTiming // First)
RM[l_]      := (Inner[And, l[[1]], l[[2]], List]; // AbsoluteTiming // First)


Test I

l1 = RandomChoice[{True, False}, {2, 10^5}];
Argento[l1]
Brett[l1]
Artes[l1]
kguler[l1]
RM[l1]

0.2710000
0.0820000
0.0530000
0.0520000
0.0390000


Test II

l2 = RandomChoice[{True, False}, {2, 7 10^5}];
Argento[l2]
Brett[l2]
Artes[l2]
kguler[l2]
RM[l2]

1.4690000
0.5820000
0.3840000
0.3700000
0.2890000


Test III

l3 = RandomChoice[{True, False}, {2, 3 10^6}];
Argento[l3]
Brett[l3]
Artes[l3]
kguler[l3]
RM[l3]

6.2320000
2.4750000
1.6530000
1.4150000
1.2150000

• \o/ yay, good timings for me! :D Usually all the fast ones are posted before I get here
– rm -rf
Commented Sep 4, 2012 at 21:49
• @R.M These posts appear to be a good promotion of Inner! Commented Sep 4, 2012 at 21:57
• @Artes, just added another one to benchmark...
– kale
Commented Sep 5, 2012 at 1:03

I prefer using Inner for this, as conceptually, it is a generalized dot of the two Boolean lists with And as the operator.

Inner[And, {True, True, False}, {True, False, False}, List]
(* {True, False, False} *)

• This might give the Wizard a conniption ;) : {True, True, False} ~(Inner[And, ##, List] &)~ {True, False, False}. Commented Sep 4, 2012 at 22:05
• @J.M. You need to go deeper... {True, True, False} ~(And ~Sequence~ #1 ~Inner~ (#2 ~Sequence~ List) &)~ {True, False, False} INFIXTION
– rm -rf
Commented Sep 4, 2012 at 23:29
• @R.M True ~Sequence~ True ~List~ False ~(Null ~Function~ (And ~Sequence~ #1 ~Inner~ (#2 ~Sequence~ List)))~ (True ~Sequence~ False ~List~ False)  Commented Sep 5, 2012 at 5:25
• @OleksandrR. I once managed to really piss Mr.Wizard off by mocking him with a ~Rule~ b instead of the natural infix a -> b :)
– rm -rf
Commented Sep 5, 2012 at 5:30

I like Artes' and kguler's answers, but I'd like to point out that in general

f @@ # & /@ list


can be more concisely written as

f @@@ list


For example:

And @@@ Transpose[{{True, True, False}, {True, False, False}}]

(* {True, False, False} *)


You can use Thread:

Thread[And[{True, True, False}, {True, False, False}]]


or, Thread with Apply (@@) :

Thread[And@@{{True, True, False}, {True, False, False}}]
(* {True, False, False} *)


Late to the party

BitAnd @@ Boole@l /. {1 -> True, 0 -> False}

• Why not simply BitAnd @@ Boole@l /. {1 -> True, 0 -> False}? What does Dispatch@ add? Commented Sep 5, 2012 at 4:04
• @DavidCarraher it adds a tiny bit of extra speed that I didn't expect either with such a short simple list of rules. I'll edit it out anyway to favour cleanliness
– Rojo
Commented Sep 5, 2012 at 11:03
• +1 I thought about submitting BitAnd@@Boole@l myself but was disappointed that there was no short command to unBoole the outcome. Perhaps ReplaceAll is the best way to unBoole. Commented Sep 5, 2012 at 13:04
• @DavidCarraher, yeah, almost the same happened to me, disappointing, but I am more of a first post (then think/delete) person
– Rojo
Commented Sep 5, 2012 at 13:12

A silly one (convert both lists to numbers, multiply, convert back) and some timings:

(l1 /. {True -> 1, False -> 0}) (l2 /. {True -> 1, False -> 0}) /. {0 -> False, 1 -> True})

n = 1000000;
res = Table[
l1 = RandomChoice[{True, False}, n];
l2 = RandomChoice[{True, False}, n];
{
(r1 = And[l1, l2] // Thread) // AbsoluteTiming // First,
(r2 = And @@@ Transpose[{l1, l2}]) // AbsoluteTiming // First,
(r3 = MapThread[And, {l1, l2}]) // AbsoluteTiming // First,
(r4 = Inner[And, l1, l2, List]) // AbsoluteTiming // First,
(r5 = (l1 /. {True -> 1, False -> 0}) (l2 /. {True -> 1,
False -> 0}) /. {0 -> False, 1 -> True}) // AbsoluteTiming // First
}, {10}];

Mean /@ (res\[Transpose])


{0.3687211, 0.6879394, 0.5338305, 0.3507201, 0.7428425}

Inner wins.

• @artes Yeah, I beat you by two minutes though ;-) Anyway, it confirms that Inner is the winner. Commented Sep 4, 2012 at 21:41

I want in on this fun. Doesn't seem to be the fastest, but here it is:

l1={{True,True,False},{True,False,False}};
(# != 0) & /@ Times @@ Boole[l1];

(*{True,False,False}*)


And in a late bid for the silver medal by subversive means:

Unprotect@And; SetAttributes[And, {Flat, OneIdentity, Protected, Listable}];

l1 = RandomChoice[{True, False}, {2, 10^6}];

Argento[l1]
Brett[l1]
Artes[l1]
kguler[l1]
RM[l1]
And @@ l1 // AbsoluteTiming // First


0.705648 0.288288 0.193292 0.163886 0.149485 0.160957

• That this is very close in performance to kguler's suggestion is no coincidence: setting Listable on something that ordinarily would not be just calls Thread automatically. The 2ms difference is probably not significant. And please, use InternalInheritedBlock or similar when resetting attributes on system functions! Commented Sep 5, 2012 at 6:30
• @OleksandrR. Is there any documentation on InheritedBlock ? Commented Sep 5, 2012 at 6:49
• Alexey has written it up here, but there's no (public) official documentation that I know of. If you don't want to use undocumented functions, you can either use a Listable wrapper function, e.g. Function[Null, And[##], {Flat, Listable}] (though this is not very efficient), or just a normal Block`. Commented Sep 5, 2012 at 7:51
• @OleksandrR. Thank you a very useful link. Commented Sep 5, 2012 at 10:44