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-boolean elements in the iterable are perfectly acceptable — bool(x) maps, or coerces, any x according to these rules:
0,0.0,None,[],(),[],set(), and other empty collections are mapped toFalse- all other values are mapped to
True.
The docstring for bool uses the terms 'true'/'false' for 'truthy'/'falsy', and True/False for the concrete boolean values.
For example:
if all(x > 0 for x in xs) or any(x > 100 for x in xs):
# if nothing is zero or something is over a hundred …
In your specific code samples:
You’ve slightly misunderstood how these functions work. The following does something completely different from 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 or a 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 the value held by big_foobar, and (lazily) emits the resulting boolean into the resulting sequence of booleans:
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. It's 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
Answer from Erik Kaplun on Stack OverflowGenerally 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-boolean elements in the iterable are perfectly acceptable — bool(x) maps, or coerces, any x according to these rules:
0,0.0,None,[],(),[],set(), and other empty collections are mapped toFalse- all other values are mapped to
True.
The docstring for bool uses the terms 'true'/'false' for 'truthy'/'falsy', and True/False for the concrete boolean values.
For example:
if all(x > 0 for x in xs) or any(x > 100 for x in xs):
# if nothing is zero or something is over a hundred …
In your specific code samples:
You’ve slightly misunderstood how these functions work. The following does something completely different from 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 or a 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 the value held by big_foobar, and (lazily) emits the resulting boolean into the resulting sequence of booleans:
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. It's 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
For the question in the title:
if a list contains one set of values or another
it might be more natural to use set operations. In other words, instead of
if any(x==playerOne for x in board) or any(x==playerTwo for x in board):
# or
if playerOne in board or playerTwo in board:
use set.issubset (or set.intersection1):
if {playerOne, playerTwo}.issubset(board):
# or
if {playerOne, playerTwo} & set(board):
If playerOne and playerTwo are set/list/tuple of values, then compute their union and test if it's a subset of board:
if {*playerOne,*playerTwo}.issubset(board):
Also if the question is
if every item on the board is either playerOne marker or playerTwo marker
then instead of
if all(x == playerOne or x == playerTwo for x in board):
test set equality:1
if {playerOne, playerTwo} == set(board):
1 You can obviously assign set(board) to some variable beforehand so that you don't have to cast board to a set every time you need to test this condition.