List comprehensions in Python are a great feature but also a little hard to wrap your head around at first. Basically a list comprehension is a one line for loop that outputs a list.

Let’s see a simple example. Suppose we wanted to output a list of five numbers, 0-4. If we use Python’s built-in range function we can do this with a simple for loop:

numbers = []
for x in range(5):
    numbers.append(x)
numbers #[0, 1, 2, 3, 4]

With a list comprehension, we can write this in one line:

my_numbers = [x for x in range(5)]
my_numbers #[0, 1, 2, 3, 4]

Powerful, right? But also a little confusing still since we haven’t described how the first “x” in our list comprehension differs from the second “x”. So let’s use square the numbers from 0-4 to see how position matters:

squares = []
for x in range(5):
    squares.append(x**2)

squares #[0, 1, 4, 9, 16, 25]

Or with a list comprehension:

squares = [x**2 for x in range(5)] #[0, 1, 4, 9, 16, 25]

Our output expression comes first, in this case x**2, followed by a for clause around our variable, x, and then our input sequence, range(5).

For beginners, the multiple “x”s here can be confusing, so let’s show what happens if the output expression and the variable are not the same thing. Here we’ve changed the output expression to a**2 and the variable to b.

squares = [a**2 for b in range(5)]
Traceback (most recent call last):
    File "<stdin>", line 1, in <module>
    File "<stdin>", line 1, in <listcomp>
    TypeError: unsupported operand type(s) for ** or pow(): 'list' and 'int'

We get a TypeError because we’re trying to do an operation on something that doesn’t exist.

But if we changed the variable and output expression to match, things will work, regardless of what we call them.

squares = [a**2 for a in range(5)]
squares #[0, 1, 4, 9, 16]

Finally, let’s get crazy and call our variable this_could_be_anything to drive the point home further.

squares = [this_could_be_anything**2 for this_could_be_anything in range(5)]
squares #[0, 1, 4, 9, 16]

Still works, see?

There’s much more we can do with list comprehensions, especially around nesting. Now that we’ve covered the basics, the official Python docs which cover this all in detail will hopefully make more sense!