137
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?

1

8 Answers 8

262
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.

4
  • 1
    For the lazy ones: here is a link to the docs.
    – Matt3o12
    Commented Oct 18, 2014 at 2:05
  • As far as first expression uses generator, does it stop at first None appearance?Also, why the 2nd expression is faster? Make no sense to me.
    – soupault
    Commented Jun 10, 2015 at 9:25
  • 3
    @s0upa1t all stops when it finds the first falsy object. The second is faster at least under CPython as the method .count on the objects of the list type is built-in and written in C and unlike the generator it doesn't have interpreter involved in the loop over the list.
    – Dan D.
    Commented Jun 10, 2015 at 14:12
  • Seconding Dan D. as all(v is None for v in l) will return true if you have a 0 in-place of a None
    – virtualxtc
    Commented Sep 8, 2018 at 10:44
85

For the specific use case in the question, you can use

not any(my_list)

This returns True if all items of my_list are falsy. Since the only objects in your list are match objects and Nones, and match objects are always trucy, this will give the same result as all(x is None for x in my_list). As demonstrated in gnibbler's answer, using not any(my_list) is much faster.

20
  • 16
    This one fails for numeric values less than 1 which are considered falsy Commented Jun 29, 2011 at 9:51
  • 6
    @Sven, how is my comment irrelevant for the question? He asked about a function which can detect if a list only contains None values. Your example would handle [0, None] the same way as a list containg [None, None]. I see me mistake about negative numbers, I'm not sure where I've got this from! Commented Jun 29, 2011 at 11:27
  • 3
    @Dog: The question explains clearly that the list consists of return values of re.match() which are either None or a match object, so it simply does not matter that this solution would fail for 0. I added some explanation to make this clearer. Commented Jun 29, 2011 at 11:31
  • 2
    Re-read his question. Both in the title AND the body, he explicitly asked "are all None", not "are all falsey".
    – SleepyCal
    Commented Aug 23, 2014 at 12:42
  • 2
    @sleepycal: I generally try to give answers that solve people's problems, instead of answering exactly what they think their problem is ("XY problem"). The question makes the actual problem quite clear (determine if none of the patterns in the list match), and my answer is a concise and fast solution to that problem. Commented Aug 23, 2014 at 14:58
20

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
8

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
4
  • 2
    Both of these need to iterate over the whole list even if the 1st element is not None. Commented Jun 29, 2011 at 10:37
  • @gnibbler - yes, you are right, added one more 'ugly' solution that would not iterate through all items Commented Jun 29, 2011 at 10:42
  • A more succinct definition of is_empty(my_list) would be return not any(my_list). At the very least, you should omit the first two lines. Commented Jun 29, 2011 at 11:04
  • @Sven - yes - you are right, simply trying to not duplicate other solution but provide the same functionality. I know that it was already discussed and 'all' method is a guru way)) but i am not a guru - i am simply learning new thing Commented Jun 29, 2011 at 11:11
2

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.

0
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
3
  • aside from being very verbose compared to the standard answers, it baffles me why you would use lambda here instead of the simple def.
    – RoundTower
    Commented Jun 29, 2011 at 10:41
  • @RoundTower, because he asked for a one-liner. I made a guess he would use it as an inline function since he already used lambda's in his example. Commented Jun 29, 2011 at 11:33
  • 1
    @RoundTower "baffles" ? the def is a few more lines by the time you include the requisite blank lines spaces surrounding functions. I don't understand why python programmers do not care about code length bloat - it's a lot more screen real estate. We're not talking about condensing fifty lines into one a la' perl code golf but also not expanding one or two lines into 5 or 10 Commented Jun 1, 2019 at 13:52
0

If you expect some items to not be None, then I would avoid looping through the entire list.

def check_none(l):
    for x in l:
        if not x is None:
            return False
    return True
0

Checking if all elements in all_none are None.

all_none = [None, None, None]

all_none == ([None] * len(all_none))
True

Not the answer you're looking for? Browse other questions tagged or ask your own question.