How to check if a list is empty in Python
There is one idiomatic way to do this, it is also the fastest, and it catches rather more than an empty list — which is fine until the day it is not.
The answer
if not items:
...
if not empty : True
if not full : False
PEP 8 is explicit about this: “For sequences, use the fact that empty sequences are false.”
It is also the fastest
Two million iterations each:
not x : 0.0154 s
len(x) == 0 : 0.0293 s
x == [] : 0.0509 s
not x calls the object’s truth test, which for a list is a length check
straight off the object header. len(x) == 0 does the same work and then
builds an integer and compares it. x == [] builds a whole new empty list
first and then runs a full sequence comparison.
None of this matters in a loop that runs ten times. It is nice that the readable version is also the cheap one.
What else it catches
Here is the catch, and it is worth knowing before you rely on the idiom:
not [] -> True not '' -> True
not () -> True not 0 -> True
not {} -> True not 0.0 -> True
not set() -> True not None -> True
not False -> True
not x is true for an empty list, an empty string, zero, and None. So this
function cannot tell the difference between “you gave me an empty list” and
“you gave me nothing at all”:
def process(items=None):
if not items:
return "nothing to do"
process([]) : nothing to do
process(None) : nothing to do
Usually that is exactly what you want — both mean “no work”. Occasionally it is not, and then you have to say so:
def process_strict(items):
if items is None:
return "no list was given"
if not items:
return "an empty list was given"
strict, [] : an empty list was given
strict, None : no list was given
The rule I use: if None and empty mean the same thing to the caller, use
not items. If the distinction is meaningful — “field absent” versus “field
present but empty”, which is common with JSON — check for None explicitly.
It does not work on generators
This one is a genuine trap, because there is no error:
bool(a generator) : True
bool(an empty generator) : True
list(empty_gen()) : []
A generator is always truthy. It has no length, and it cannot know whether it will produce anything without running — which would consume the value it produced.
So if not gen: is always false, whatever the generator does. To find out
whether there is anything in it you have to ask for an item:
sentinel = object()
if next(gen, sentinel) is sentinel:
... # it was empty
next(empty_gen(), sentinel) is sentinel : True
Note that this consumes the first item, so you need to use the value you just pulled rather than iterating from the start.
The same applies to anything lazy — a file object, a map, a zip, a database
cursor. If you need to test for emptiness, either materialise it with list()
or restructure so you do not need to.
Custom classes get it for free
class Basket:
def __len__(self):
return len(self.items)
bool(Basket([])) : False
bool(Basket([1])) : True
Defining
__len__
is enough — Python falls back to it when there is no __bool__. If you define
both, __bool__ wins, which is worth knowing if you ever want a container that
is truthy while empty.
A note on numpy and pandas
If items might be a numpy array or a pandas Series, if not items: raises:
ValueError: The truth value of an array with more than one element is ambiguous.
Use a.any() or a.all()
They refuse to guess whether you meant “any element is true” or “the container
is non-empty”. Use .size == 0 for numpy, or .empty for a pandas DataFrame
or Series. The article on iterating DataFrames covers the same error from the
other direction.
About Netcup (advertisement)
The German host Netcup offers, among other things, affordable and powerful web hosting packages, KVM-based root servers and dedicated servers. With our voucher codes you can save even more (6€ off your first order, 30% off all KVM-based root servers, ...).