How to check if all items in the list are None?
PythonPython Problem Overview
In [27]: map( lambda f,p: f.match(p), list(patterns.itervalues()), vatids )
Out[27]: [None, <_sre.SRE_Match object at 0xb73bfdb0>, None]
The list can be all None
or one of it is an re.Match instance.
What one liner check can I do on the returned list to tell me that the contents are all None
?
Python Solutions
Solution 1 - Python
all(v is None for v in l)
will return True
if all of the elements of l
are None
Note that l.count(None) == len(l)
is a lot faster but requires that l
be an actual list
and not just an iterable.
Solution 2 - Python
not any(my_list)
returns True
if all items of my_list
are falsy.
Edit: Since match objects are always truthy and None
is falsy, this will give the same result as all(x is None for x in my_list)
for the case at hand. As demonstrated in gnibbler's answer, using any()
is by far the faster alternative.
Solution 3 - Python
Since Match objects are never going to evaluate to false, it's ok and much faster to just use not any(L)
$ python -m timeit -s"L=[None,None,None]" "all( v is None for v in L )"
100000 loops, best of 3: 1.52 usec per loop
$ python -m timeit -s"L=[None,None,None]" "not any(L)"
1000000 loops, best of 3: 0.281 usec per loop
$ python -m timeit -s"L=[None,1,None]" "all( v is None for v in L )"
100000 loops, best of 3: 1.81 usec per loop
$ python -m timeit -s"L=[None,1,None]" "not any(L)"
1000000 loops, best of 3: 0.272 usec per loop
Solution 4 - Python
Or a bit weird but:
a = [None, None, None]
set(a) == set([None])
OR:
if [x for x in a if x]: # non empty list
#do something
EDITED:
def is_empty(lVals):
if not lVals:
return True
for x in lVals:
if x:
return False
return True
Solution 5 - Python
is_all_none = lambda L: not len(filter(lambda e: not e is None, L))
is_all_none([None,None,'x'])
False
is_all_none([None,None,None])
True
Solution 6 - Python
I managed to come up with an approach using map
that hasn't been given yet
tl;dr
def all_none(l):
return not any(map(None.__ne__, l))
all_none([None, None, None]) # -> True
all_none([None, None, 8]) # -> False
explanation
The use of None.__ne__
is bit weirder than you'd expect at first glance. This method returns a NotImplementedType
object when given something that isn't None.
You'd be hoping that NotImplemented
would be a stand-in for False
, however it's truthy too! This means that using None.__eq__
across a collection will produce thruthy values for everything.
list(map(None.__eq__, [None, None, 8]))
# -> [True, True, NotImplemented]
all(list(map(None.__eq__, [None, None, 8])))
# -> True
From the Python Docs: > By default, an object is considered true unless its class defines > either a bool() method that returns False or a len() method > that returns zero
Instead, None.__ne__
returns False
for any None
elements, and a
NotImplementedType
object for anything else:
list(map(None.__ne__, [None, None, 8]))
# -> [False, False, NotImplemented]
Using this, you can check if any
elements are not None
which will return True
. I like to think of this as 2 separate methods if that helps with the mental negation gymnastics.
def contains_truthy(l):
return any(map(None.__ne__, l))
def all_none(l):
return not contains_truthy(l)
I haven't done any benchmarking with this, but as mentioned by others in this thread, not any
will produce fast results.