开发者

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
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜