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. – DavidC Sep 4 '12 at 16:51
Related: (3217) – Mr.Wizard 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 – R. M. Sep 4 '12 at 21:49
@R.M These posts appear to be a good promotion of Inner! – Artes 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}. – J. M. 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 – R. M. 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) – Oleksandr R. 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 :) – R. M. 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} *)
-

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? – DavidC 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. – DavidC 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. – Sjoerd C. de Vries 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 Internal`InheritedBlock or similar when resetting attributes on system functions! – Oleksandr R. Sep 5 '12 at 6:30
@OleksandrR. Is there any documentation on InheritedBlock ? – image_doctor 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. – Oleksandr R. Sep 5 '12 at 7:51
@OleksandrR. Thank you a very useful link. – image_doctor Sep 5 '12 at 10:44