How to check if all items in the list are None?
In [27]: map( lambda f,p: f.match(p), list(patterns.itervalues()), vatids )
Out[27]: [None, <_sre.SRE_Match object at 0xb73bfdb0>, Non开发者_开发问答e]
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
?
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.
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.
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
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
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.
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
精彩评论