## How do I check if a list is empty?

### Question

For example, if passed the following:

``````a = []
``````

How do I check to see if `a` is empty?

2018/11/18
1
3233
11/18/2018 11:13:03 AM

``````if not a:
print("List is empty")
``````

Using the implicit booleanness of the empty `list` is quite pythonic.

2020/05/28
5722
5/28/2020 6:08:32 PM

The pythonic way to do it is from the PEP 8 style guide (where Yes means “recommended” and No means “not recommended”):

For sequences, (strings, lists, tuples), use the fact that empty sequences are false.

``````Yes: if not seq:
if seq:

No:  if len(seq):
if not len(seq):
``````
2018/03/26

I prefer it explicitly:

``````if len(li) == 0:
print('the list is empty')
``````

This way it's 100% clear that `li` is a sequence (list) and we want to test its size. My problem with `if not li: ...` is that it gives the false impression that `li` is a boolean variable.

2017/09/09

This is the first google hit for "python test empty array" and similar queries, plus other people seem to be generalizing the question beyond just lists, so I thought I'd add a caveat for a different type of sequence that a lot of people might use.

## Other methods don't work for NumPy arrays

You need to be careful with NumPy arrays, because other methods that work fine for `list`s or other standard containers fail for NumPy arrays. I explain why below, but in short, the preferred method is to use `size`.

### The "pythonic" way doesn't work: Part 1

The "pythonic" way fails with NumPy arrays because NumPy tries to cast the array to an array of `bool`s, and `if x` tries to evaluate all of those `bool`s at once for some kind of aggregate truth value. But this doesn't make any sense, so you get a `ValueError`:

``````>>> x = numpy.array([0,1])
>>> if x: print("x")
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()
``````

### The "pythonic" way doesn't work: Part 2

But at least the case above tells you that it failed. If you happen to have a NumPy array with exactly one element, the `if` statement will "work", in the sense that you don't get an error. However, if that one element happens to be `0` (or `0.0`, or `False`, ...), the `if` statement will incorrectly result in `False`:

``````>>> x = numpy.array([0,])
>>> if x: print("x")
... else: print("No x")
No x
``````

But clearly `x` exists and is not empty! This result is not what you wanted.

### Using `len` can give unexpected results

For example,

``````len( numpy.zeros((1,0)) )
``````

returns 1, even though the array has zero elements.

### The numpythonic way

As explained in the SciPy FAQ, the correct method in all cases where you know you have a NumPy array is to use `if x.size`:

``````>>> x = numpy.array([0,1])
>>> if x.size: print("x")
x

>>> x = numpy.array([0,])
>>> if x.size: print("x")
... else: print("No x")
x

>>> x = numpy.zeros((1,0))
>>> if x.size: print("x")
... else: print("No x")
No x
``````

If you're not sure whether it might be a `list`, a NumPy array, or something else, you could combine this approach with the answer @dubiousjim gives to make sure the right test is used for each type. Not very "pythonic", but it turns out that NumPy intentionally broke pythonicity in at least this sense.

If you need to do more than just check if the input is empty, and you're using other NumPy features like indexing or math operations, it's probably more efficient (and certainly more common) to force the input to be a NumPy array. There are a few nice functions for doing this quickly — most importantly `numpy.asarray`. This takes your input, does nothing if it's already an array, or wraps your input into an array if it's a list, tuple, etc., and optionally converts it to your chosen `dtype`. So it's very quick whenever it can be, and it ensures that you just get to assume the input is a NumPy array. We usually even just use the same name, as the conversion to an array won't make it back outside of the current scope:

``````x = numpy.asarray(x, dtype=numpy.double)
``````

This will make the `x.size` check work in all cases I see on this page.

2019/06/25

## Best way to check if a list is empty

For example, if passed the following:

``````a = []
``````

How do I check to see if a is empty?

Place the list in a boolean context (for example, with an `if` or `while` statement). It will test `False` if it is empty, and `True` otherwise. For example:

``````if not a:                           # do this!
print('a is an empty list')
``````

## PEP 8

PEP 8, the official Python style guide for Python code in Python's standard library, asserts:

For sequences, (strings, lists, tuples), use the fact that empty sequences are false.

``````Yes: if not seq:
if seq:

No: if len(seq):
if not len(seq):
``````

We should expect that standard library code should be as performant and correct as possible. But why is that the case, and why do we need this guidance?

## Explanation

I frequently see code like this from experienced programmers new to Python:

``````if len(a) == 0:                     # Don't do this!
print('a is an empty list')
``````

And users of lazy languages may be tempted to do this:

``````if a == []:                         # Don't do this!
print('a is an empty list')
``````

These are correct in their respective other languages. And this is even semantically correct in Python.

But we consider it un-Pythonic because Python supports these semantics directly in the list object's interface via boolean coercion.

From the docs (and note specifically the inclusion of the empty list, `[]`):

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, when called with the object. Here are most of the built-in objects considered false:

• constants defined to be false: `None` and `False`.
• zero of any numeric type: `0`, `0.0`, `0j`, `Decimal(0)`, `Fraction(0, 1)`
• empty sequences and collections: `''`, `()`, `[]`, `{}`, `set()`, `range(0)`

And the datamodel documentation:

`object.__bool__(self)`

Called to implement truth value testing and the built-in operation `bool()`; should return `False` or `True`. When this method is not defined, `__len__()` is called, if it is defined, and the object is considered true if its result is nonzero. If a class defines neither `__len__()` nor `__bool__()`, all its instances are considered true.

and

`object.__len__(self)`

Called to implement the built-in function `len()`. Should return the length of the object, an integer >= 0. Also, an object that doesn’t define a `__bool__()` method and whose `__len__()` method returns zero is considered to be false in a Boolean context.

``````if len(a) == 0:                     # Don't do this!
print('a is an empty list')
``````

or this:

``````if a == []:                     # Don't do this!
print('a is an empty list')
``````

Do this:

``````if not a:
print('a is an empty list')
``````

## Doing what's Pythonic usually pays off in performance:

Does it pay off? (Note that less time to perform an equivalent operation is better:)

``````>>> import timeit
>>> min(timeit.repeat(lambda: len([]) == 0, repeat=100))
0.13775854044661884
>>> min(timeit.repeat(lambda: [] == [], repeat=100))
0.0984637276455409
>>> min(timeit.repeat(lambda: not [], repeat=100))
0.07878462291455435
``````

For scale, here's the cost of calling the function and constructing and returning an empty list, which you might subtract from the costs of the emptiness checks used above:

``````>>> min(timeit.repeat(lambda: [], repeat=100))
0.07074015751817342
``````

We see that either checking for length with the builtin function `len` compared to `0` or checking against an empty list is much less performant than using the builtin syntax of the language as documented.

Why?

For the `len(a) == 0` check:

First Python has to check the globals to see if `len` is shadowed.

Then it must call the function, load `0`, and do the equality comparison in Python (instead of with C):

``````>>> import dis
>>> dis.dis(lambda: len([]) == 0)
2 BUILD_LIST               0
4 CALL_FUNCTION            1
8 COMPARE_OP               2 (==)
10 RETURN_VALUE
``````

And for the `[] == []` it has to build an unnecessary list and then, again, do the comparison operation in Python's virtual machine (as opposed to C)

``````>>> dis.dis(lambda: [] == [])
1           0 BUILD_LIST               0
2 BUILD_LIST               0
4 COMPARE_OP               2 (==)
6 RETURN_VALUE
``````

The "Pythonic" way is a much simpler and faster check since the length of the list is cached in the object instance header:

``````>>> dis.dis(lambda: not [])
1           0 BUILD_LIST               0
2 UNARY_NOT
4 RETURN_VALUE
``````

## Evidence from the C source and documentation

`PyVarObject`

This is an extension of `PyObject` that adds the `ob_size` field. This is only used for objects that have some notion of length. This type does not often appear in the Python/C API. It corresponds to the fields defined by the expansion of the `PyObject_VAR_HEAD` macro.

From the c source in Include/listobject.h:

``````typedef struct {
/* Vector of pointers to list elements.  list is ob_item, etc. */
PyObject **ob_item;

/* ob_item contains space for 'allocated' elements.  The number
* currently in use is ob_size.
* Invariants:
*     0 <= ob_size <= allocated
*     len(list) == ob_size
``````

I would point out that this is also true for the non-empty case though its pretty ugly as with `l=[]` then `%timeit len(l) != 0` 90.6 ns ± 8.3 ns, `%timeit l != []` 55.6 ns ± 3.09, `%timeit not not l` 38.5 ns ± 0.372. But there is no way anyone is going to enjoy `not not l` despite triple the speed. It looks ridiculous. But the speed wins out
I suppose the problem is testing with timeit since just `if l:` is sufficient but surprisingly `%timeit bool(l)` yields 101 ns ± 2.64 ns. Interesting there is no way to coerce to bool without this penalty. `%timeit l` is useless since no conversion would occur.

IPython magic, `%timeit`, is not entirely useless here:

``````In : l = []

In : %timeit l
20 ns ± 0.155 ns per loop (mean ± std. dev. of 7 runs, 100000000 loops each)

In : %timeit not l
24.4 ns ± 1.58 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)

In : %timeit not not l
30.1 ns ± 2.16 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)
``````

We can see there's a bit of linear cost for each additional `not` here. We want to see the costs, ceteris paribus, that is, all else equal - where all else is minimized as far as possible:

``````In : %timeit if l: pass
22.6 ns ± 0.963 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)

In : %timeit if not l: pass
24.4 ns ± 0.796 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)

In : %timeit if not not l: pass
23.4 ns ± 0.793 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)
``````

Now let's look at the case for an unempty list:

``````In : l = 

In : %timeit if l: pass
23.7 ns ± 1.06 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)

In : %timeit if not l: pass
23.6 ns ± 1.64 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)

In : %timeit if not not l: pass
26.3 ns ± 1 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)
``````

What we can see here is that it makes little difference whether you pass in an actual `bool` to the condition check or the list itself, and if anything, giving the list, as is, is faster.

Python is written in C; it uses its logic at the C level. Anything you write in Python will be slower. And it will likely be orders of magnitude slower unless you're using the mechanisms built into Python directly.

2019/11/28

An empty list is itself considered false in true value testing (see python documentation):

``````a = []
if a:
print "not empty"
``````

@Daren Thomas

EDIT: Another point against testing the empty list as False: What about polymorphism? You shouldn't depend on a list being a list. It should just quack like a duck - how are you going to get your duckCollection to quack ''False'' when it has no elements?

Your duckCollection should implement `__nonzero__` or `__len__` so the if a: will work without problems.

2014/09/06