This is a great opportunity to use map
, because and
can be represented with a built-in function:
import operator X = [True,False] Y = [True,True] map(operator.and_, X,Y)
The reason you execute your behavior is because and
performs operations on operands as if they applied bool
to them. All non-empty lists are evaluated in True
in a boolean context.
As for βlist comprehension is always betterβ: no. The concept of an equivalent list:
[x and y for x, y in zip(X, Y)]
Who needs to create an intermediate object (either a list or a generator, depending on the version of python), and still requires the reader to know what zip
does, how map
does. It will also probably be a little slower (because the map + function is built-in quickly - all this happens in the C layer, essentially). In fact, timeit
shows that izip
is faster (see below), but I really think that the readability point is more important; you can also see different results if performance really matters.
>>> timeit.timeit('map(operator.and_, X,Y)', 'import operator; import itertools; import random; X = [random.choice([True,False]) for _ in range(1000)]; Y = [random.choice([True,False]) for _ in range(1000)]', number=10000) 1.0160579681396484 >>> timeit.timeit('[x and y for x, y in zip(X, Y)]', 'import operator; import itertools; import random; X = [random.choice([True,False]) for _ in range(1000)]; Y = [random.choice([True,False]) for _ in range(1000)]', number=10000) 1.3570780754089355 >>> timeit.timeit('[x and y for x, y in itertools.izip(X, Y)]', 'import operator; import itertools; import random; X = [random.choice([True,False]) for _ in range(1000)]; Y = [random.choice([True,False]) for _ in range(1000)]', number=10000) 0.965054988861084
However, if you need an arbitrary number of lists, you need to use all
in understanding the list (or in combination with izip
directly); and and_
technically bitwise, so keep in mind that they may have funky results when dealing with numeric types other than bool
.
Here is the version of all
:
import itertools map(all,itertools.izip(X,Y,Z))