7

I was wondering if we could assert all elements in a list is not None, therefore while a = None will raise an error.

The sample list is [a, b, c]

I have tried assert [a, b, c] is not None, it will return True if any one of the elements is not None but not verifying all. Could you help figure it out? Thanks!!

2
  • 1
    assert [a, b, c] is not None will pass even if all the elements are None. The only thing that is None is... None. is means the same object, not an equality check. It also is not possible to create more instances of None's type. Commented Sep 6, 2021 at 3:52
  • "assert [a, b, c] is not None, it will return True if any one of the elements is not None " no. that isn't what is happening, it is doing an identity check for None. Any list is not None, in fact, any object except None is not None. Commented Sep 6, 2021 at 3:53

3 Answers 3

9

Unless you have a weird element that claims it equals None:

assert None not in [a, b, c]
Sign up to request clarification or add additional context in comments.

3 Comments

kudos, as this version also seems the fastest. If anyone curious, about 5x faster than all and checking if each element is not None, but very close in terms of performance to all([a, b, c])
@rv.kvetch all([a, b, c]) is significantly less safe, though, as any false value (e.g., a zero) will make that return False.
yep, I never said it was perfect; but somehow it performs much better than the one with the explicit None check, which seems slow by comparison.
4

Do you mean by all:

>>> assert all(i is not None for i in ['a', 'b', 'c'])
>>>

Or just simply:

assert None not in ['a', 'b', 'c']

P.S just noticed that @don'ttalkjustcode added the above.

Or with min:

>>> assert min(a, key=lambda x: x is not None, default=False)
>>>

1 Comment

default should be True, though I find min very weird for this. And for example it cries AssertionError for [0, 1, 2] even though there's no None. Btw the correct faster all(...) that I think you were trying earlier is as expected indeed faster, see @rv's benchmark.
1

Midway in terms of performence between not in and all. Note that the sensible (go-to) version with all for this particular case will end up performing slow - but at least ahead of min

def assert_all_not_none(l):
    for x in l:
        if x is None:
            return False
    return True

Edit: here are some benchmarks for those intersted

from timeit import timeit


def all_not_none(l):
    for b in l:
        if b is None:
            return False
    return True


def with_min(l):
    min(l, key=lambda x: x is not None, default=False)


def not_in(l):
    return None not in l


def all1(l):
    return all(i is not None for i in l)


def all2(l):
    return all(False for i in l if i is None)


def all_truthy(l):
    return all(l)


def any1(l):
    return any(True for x in l if x is None)


l = ['a', 'b', 'c'] * 20_000

n = 1_000

# 0.63
print(timeit("all_not_none(l)", globals=globals(), number=n))

# 3.41
print(timeit("with_min(l)", globals=globals(), number=n))

# 1.66
print(timeit('all1(l)', globals=globals(), number=n))

# 0.63
print(timeit('all2(l)', globals=globals(), number=n))

# 0.63
print(timeit('any1(l)', globals=globals(), number=n))

# 0.26
print(timeit('all_truthy(l)', globals=globals(), number=n))

# 0.53
print(timeit('not_in(l)', globals=globals(), number=n))

Surprisingly the winner: all(list). Therfore, if you are certain list will not contain falsy values like empty string or zeros, nothing wrong with going with that.

5 Comments

Those claims really make me desire to see a benchmark :-)
yep, just added some quick and dirty one with a sufficiently long list to test
I think it's a bit misleading, as all except all_not_none would normally be used inline (like if any(l):) without extra function call, while all_not_none would be used with a call (like if all_not_none(l)). But alright otherwise. Could also include the all(False ...) one I mentioned in a comment, should be faster for the same reason as this.
woah, that was a huge difference. I added another test for all and it was really much faster. nice catch :)
The any should be not any.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.