List Comprehensions

The loop that builds a list, written as one expression - and the point at which writing it that way stops helping.

Overview

The translation

Nearly every comprehension started life as this shape:

result = []
for item in things:
    result.append(f(item))

which becomes:

result = [f(item) for item in things]

Read it left to right: what to build, then where the items come from. The three moving parts of the loop — create the list, iterate, append — collapse into one line where the intent is the first thing you see.

comprehension.py

comprehension.py Python 3
Output

                    

comprehension_limits.py

comprehension_limits.py Python 3
Output

                    

Worth knowing

Read it left to right: the expression first, then where the items come from, then the filter.
The if at the end filters. There is no else there - an else belongs in the expression at the front.
Nested comprehension order matches the nested loop order: outer first.
Round brackets make a generator instead: same syntax, builds nothing, ideal inside sum() or any().

List Comprehensions: A Practical Guide

A comprehension is a loop that builds a list, written as a single expression. It is the same work in fewer lines — and past a certain complexity, in far less readable ones.

Filtering

An if at the end keeps only some items:

evens = [n for n in nums if n % 2 == 0]

That is the filter position, and it takes no else. If you want to choose between two values rather than keep or drop, the conditional goes in the expression at the front instead:

labels = ["even" if n % 2 == 0 else "odd" for n in nums]

Two different ifs, in two different places, doing two different jobs. Mixing them up is the most common comprehension error.

Nesting reads outer-first

[n for row in grid for n in row]

The clauses come in the same order as the nested loops would: for row outside, for n inside. It reads oddly because the expression sits before both, but the order after the expression is exactly the loop order.

One level of nesting is defensible. Two, plus a filter, is a line that will cost you a minute every time you come back to it — and the loop version costs nothing. The second program on this page puts both side by side and prints the same answer from each.

Comprehension or generator

Swap the brackets for round ones and you get a generator expression:

total = sum(n * n for n in range(10_000))

The comprehension builds the whole list first — every element in memory — then sums it. The generator produces one value at a time and never builds a list at all. When the result is consumed immediately by sum, any, max or a for, the generator is the better default, and the size difference is measurable: the page prints both.

The rule of thumb

Use a comprehension when it fits on one line and reads as a sentence. When you need a second for, a filter, and a conditional expression at once, write the loop. Comprehensions are for making simple transformations obvious, not for proving a loop can be compressed.

Check yourself

0 of 3

Answer without scrolling back up.

  1. Where does the filtering `if` go in a comprehension?

  2. What does `(n * n for n in nums)` create?

  3. In `[n for row in grid for n in row]`, which loop is the outer one?

Cheat sheet

List Comprehensions

A comprehension is a loop that builds a list, written as a single expression. It is the same work in fewer lines — and past a certain complexity, in far less readable ones.

PYTHON · vizlearn.in/python/list_comprehensions.html

About the author

Ashish Jangra builds and maintains VizLearn. Every module here is written and the visualisation behind it hand-built, so the numbers in a readout come from the same code that draws the picture. Corrections are genuinely welcome and get priority over everything else — if a page states something wrong, or an animation misrepresents what the algorithm does, get in touch.