# 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. Sep 4 '12 at 16:51
• Related: (3217) Jan 18 '15 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
Sep 4 '12 at 21:49
• @R.M These posts appear to be a good promotion of Inner! Sep 4 '12 at 21:57
• @Artes, just added another one to benchmark...
– kale
Sep 5 '12 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}. Sep 4 '12 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
Sep 4 '12 at 23:29
• @R.M True ~Sequence~ True ~List~ False ~(Null ~Function~ (And ~Sequence~ #1 ~Inner~ (#2 ~Sequence~ List)))~ (True ~Sequence~ False ~List~ False)  Sep 5 '12 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
Sep 5 '12 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? Sep 5 '12 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
Sep 5 '12 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. Sep 5 '12 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
Sep 5 '12 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. Sep 4 '12 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! Sep 5 '12 at 6:30
• @OleksandrR. Is there any documentation on InheritedBlock ? Sep 5 '12 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`. Sep 5 '12 at 7:51
• @OleksandrR. Thank you a very useful link. Sep 5 '12 at 10:44