Build a new list from an iterable in one readable line: transform each item, and optionally filter.
Runs first: where the items come from, one at a time.
Checked next: items that fail it are skipped.
Written first, computed last: what goes into the new list for each kept item.
# basic comprehension
squares = [x**2 for x in range(5)]
# ans: [0, 1, 4, 9, 16]
# transform items
words = ["hello", "world"]
upper = [word.upper() for word in words]
# ans: ['HELLO', 'WORLD']
# filter with condition
evens = [x for x in range(10) if x % 2 == 0]
# ans: [0, 2, 4, 6, 8]
# multiple filters
numbers = [x for x in range(20)
if x % 2 == 0
if x % 3 == 0]
# ans: [0, 6, 12, 18]
Two if clauses must both pass, like and.
# if-else (not filter)
result = ["even" if x % 2 == 0 else "odd"
for x in range(5)]
# ans: ['even', 'odd', 'even', 'odd', 'even']
An if-else before for chooses a value for every item; an if after for drops items.
# nested loops
pairs = [(x, y) for x in range(3)
for y in range(2)]
# ans: [(0,0), (0,1), (1,0), (1,1), (2,0), (2,1)]
The first for is the outer loop: y runs through all its values for each x.
# flatten
nested = [[1, 2], [3, 4], [5, 6]]
flat = [item for sublist in nested
for item in sublist]
# ans: [1, 2, 3, 4, 5, 6]
Predict the list, then press → to check.
# basic comprehension?
[x*2 for x in range(3)]
# ans: [0, 2, 4]
# with filter?
[x for x in range(10) if x > 5]
# ans: [6, 7, 8, 9]
# if-else position?
[x if x > 0 else 0 for x in [-1, 1, -2, 2]]
# ans: [0, 1, 0, 2]
# nested comprehension?
[[i*j for j in range(3)] for i in range(2)]
# ans: [[0, 0, 0], [0, 1, 2]]
The inner comprehension builds one whole row for each i.
# string comprehension?
[c.upper() for c in "abc"]
# ans: ['A', 'B', 'C']
# multiple filters?
[x for x in range(20) if x % 2 == 0 if x % 5 == 0]
# ans: [0, 10]
Comprehension vs loop?
[x**2 for x in range(3)]
result = []
for x in range(3):
result.append(x**2)
Same result: [0, 1, 4]. The comprehension is shorter and builds the list for you.
# empty comprehension?
[x for x in range(0)]
# ans: []
# tuple in comprehension?
[(x, x**2) for x in range(3)]
# ans: [(0, 0), (1, 1), (2, 4)]
# flatten with condition?
nested = [[1,2,3], [4,5,6]]
[x for sublist in nested
for x in sublist if x % 2 == 0]
# ans: [2, 4, 6]
[expression for item in iterable if condition]
if after for drops items; a if c else b before for picks a value.
The first for is the outer loop, as in the equivalent nested loops.
If it no longer fits on a line or two, write the loop instead.