python – Using any() and all() to check if a list contains one set of values or another
python – Using any() and all() to check if a list contains one set of values or another
Generally speaking:
all
and any
are functions that take some iterable and return True
, if
- in the case of
all()
, no values in the iterable are falsy; - in the case of
any()
, at least one value is truthy.
A value x
is falsy iff bool(x) == False
.
A value x
is truthy iff bool(x) == True
.
Any non-booleans in the iterable will be fine — bool(x)
will map (or coerce, if you prefer) any x
according to these rules: 0
, 0.0
, None
, []
, ()
, []
, set()
, and other empty collections get mapped to False
, anything else to True
. The docstring for bool
uses the terms true/false for truthy/falsy, and True
/False
for the concrete boolean values.
In your specific code samples:
You misunderstood a little bit how these functions work. Hence, the following does something completely not what you thought:
if any(foobars) == big_foobar:
…because any(foobars)
would first be evaluated to either True
or False
, and then that boolean value would be compared to big_foobar
, which generally always gives you False
(unless big_foobar
coincidentally happened to be the same boolean value).
Note: the iterable can be a list, but it can also be a generator/generator expression (≈ lazily evaluated/generated list) or any other iterator.
What you want instead is:
if any(x == big_foobar for x in foobars):
which basically first constructs an iterable that yields a sequence of booleans—for each item in foobars
, it compares the item to big_foobar
and emits the resulting boolean into the resulting sequence:
tmp = (x == big_foobar for x in foobars)
then any
walks over all items in tmp
and returns True
as soon as it finds the first truthy element. Its as if you did the following:
In [1]: foobars = [big, small, medium, nice, ugly]
In [2]: big_foobar = big
In [3]: any([big == big_foobar, small == big_foobar, medium == big_foobar, nice == big_foobar, ugly == big_foobar])
Out[3]: True
Note: As DSM pointed out, any(x == y for x in xs)
is equivalent to y in xs
but the latter is more readable, quicker to write and runs faster.
Some examples:
In [1]: any(x > 5 for x in range(4))
Out[1]: False
In [2]: all(isinstance(x, int) for x in range(10))
Out[2]: True
In [3]: any(x == Erik for x in [Erik, John, Jane, Jim])
Out[3]: True
In [4]: all([True, True, True, False, True])
Out[4]: False
See also: http://docs.python.org/2/library/functions.html#all