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.
>>> L1 = [2,3,4]
>>> L2 = [1,2]
>>> [i for i in L1 if i in L2]
[2]
>>> S1 = set(L1)
>>> S2 = set(L2)
>>> S1.intersection(S2)
set([2])
Both empty lists and empty sets are False, so you can use the value directly as a truth value.
I was thinking of this slight variation on Tobias' solution:
>>> a = [1,2,3,4]
>>> b = [2,7]
>>> any(x in a for x in b)
True
Find all items from one list that are not in another list
python - Checking if any elements in one list are in another - Stack Overflow
how to check if an element of a nested list appears in another list?
Is there a more efficient way to check if at least one value is present in a list of values?
Hello all,
I am trying to create a list (list3) of all items that are exist in one list (list1), but do not exist in another list (list2). Any help would be greatly appreciated!
I am using pandas / data frames to create two lists each made of the items in a column in different excel files and I want to identify the items in list1 that are not found in list2.
Basically I have:
Df1 = pd.read_excel(file1)
Df2 = pd.read_excel(file2)
List1 = df1['Column Name']
List2 = df2['Column Name']
List3 = [x for x in List1 if x not in List2]
This is basically just recreating List1 and not omitting the entries that exist in List2.
Thank you all in advance! Please let me know if you need more info
You could solve this many ways. One that is pretty simple to understand is to just use a loop.
def comp(list1, list2):
for val in list1:
if val in list2:
return True
return False
A more compact way you can do it is to use map and reduce:
reduce(lambda v1,v2: v1 or v2, map(lambda v: v in list2, list1))
Even better, the reduce can be replaced with any:
any(map(lambda v: v in list2, list1))
You could also use sets:
len(set(list1).intersection(list2)) > 0
There are different ways. If you just want to check if one list contains any element from the other list, you can do this..
not set(list1).isdisjoint(list2)
I believe using isdisjoint is better than intersection for Python 2.6 and above.
Here's what I've got so far:
list1 = ["a", ["b", "c"], ["d", "e"]] list2 = ["b", "c", "f"] check = any(item in list1 for item in list2) print(check)
How would I check whether or not list2 contains an element of list1, including one of the nested lists? It returns True if I put "a" in list2, but gives False as it is right now. I'm pretty sure this is because it's checking single items, but I don't know how to make it work.
Any help would be greatly appreciated!
Let's say I have the following variables and list:
x = 1 y = 2 z = [2, 4, 6]
and I want to check if either x or y is in z. Obviously I can do this:
if x in z or y in z
but that seems very inefficient because of the repetition, especially if there are more than two values to check and if the variable/list names are much longer than single letters.
Is there a more concise way to write this that is still considered Pythonic? I know the following won't work because x (and therefore the entire if statement) will always evaluate to True, but maybe something similar:
if x or y in z
Thanks!
Operators like <= in Python are generally not overriden to mean something significantly different than "less than or equal to". It's unusual for the standard library does this--it smells like legacy API to me.
Use the equivalent and more clearly-named method, set.issubset. Note that you don't need to convert the argument to a set; it'll do that for you if needed.
set(['a', 'b']).issubset(['a', 'b', 'c'])
I would probably use set in the following manner :
set(l).issuperset(set(['a','b']))
or the other way round :
set(['a','b']).issubset(set(l))
I find it a bit more readable, but it may be over-kill. Sets are particularly useful to compute union/intersection/differences between collections, but it may not be the best option in this situation ...