Python 101Free
IDIOMATIC PYTHON

Comprehensions

Building collections inline from an expression and a loop.

SECTION 01

List, dict, set comprehensions

A list comprehension fuses a for loop and an append call into a single expression. [x * x for x in nums] builds a new list of squared numbers. The syntax reads as "this expression, for each x in nums".

Dict and set comprehensions follow the same pattern with different brackets. {x: x*x for x in nums} is a dict, {x*x for x in nums} is a set. The optional if filter ([x for x in nums if x > 0]) lets you skip elements.

Comprehensions are not just a shortcut. They are the idiomatic way to build collections in Python. A reader sees the brackets and knows what kind of result is being constructed without having to track an accumulator across multiple lines.

python
nums = [1, 2, 3, 4]

[x * x for x in nums if x > 1]   # [4, 9, 16]
{x: x * x for x in nums}         # {1: 1, 2: 4, 3: 9, 4: 16}
{x % 2 for x in nums}            # {0, 1}
SECTION 02

Generator expressions

Replace the square brackets with parentheses and the comprehension becomes a generator expression. (x * x for x in nums) does not build a list. It produces values one at a time, only when something asks for the next one.

The practical effect is memory. A list comprehension over a billion-item iterable would build a billion-item list. The generator version holds one value in flight and forgets the rest. For pipelines where you stream data through several stages, this is the difference between "works" and "runs out of memory".

Use a generator expression whenever the consumer only needs to iterate once, especially for large or unbounded data. Use a list comprehension whenever you need random access, length, or to iterate the result more than once.

python
squares = (x * x for x in range(10**9))   # lazy, no memory blow-up
next(squares)   # 0
next(squares)   # 1

sum(x * x for x in range(1000))   # parens optional inside a call
NEXT →
Iterators and Generators