Python List Comprehension Cheat Sheet
List comprehensions are Python's most distinctive feature: they pack filter, map, and flatten into a single expression. This cheat sheet covers the basic map-and-filter form, the nested form for cartesian products and matrix flattening, and the conditional-expression form that branches inside the output. Each pattern shows up many times per Python file in real codebases.
452 views
11
numbers = [1, 2, 3, 4, 5, 6]
squares = [n * n for n in numbers]
print(squares) # [1, 4, 9, 16, 25, 36]
even_squares = [n * n for n in numbers if n % 2 == 0]
print(even_squares) # [4, 16, 36]
lower = [s.lower() for s in ['Alpha', 'BETA', 'Gamma']]
print(lower) # ['alpha', 'beta', 'gamma']The base form [expr for x in iterable] is a map. Adding if condition filters which items contribute. Reading order matches normal Python: 'square each number', 'square each number where n is even'. Comprehensions are not just shorter than for plus append, they are also faster because the interpreter avoids the per-iteration LOAD_METHOD overhead. Reach for them whenever the loop body is a single expression and you produce a list.
matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
flat = [x for row in matrix for x in row]
print(flat) # [1, 2, 3, 4, 5, 6, 7, 8, 9]
pairs = [(a, b) for a in [1, 2] for b in ['x', 'y']]
print(pairs) # [(1, 'x'), (1, 'y'), (2, 'x'), (2, 'y')]
upper_triangle = [(i, j) for i in range(3) for j in range(i + 1, 3)]
print(upper_triangle) # [(0, 1), (0, 2), (1, 2)]Multiple for clauses chain like nested loops, with the leftmost being the outermost. The order is: [x for row in matrix for x in row] reads as 'for each row, for each x in row, take x'. Filters can reference earlier loop variables, which is what makes the upper-triangle pattern work without an explicit second loop. The same shape produces cartesian products, adjacency lists, and any combinatorial sweep. Watch the readability ceiling: more than two for clauses usually deserve a real for loop.
nums = [-3, -1, 0, 2, 4]
clamped = [n if n >= 0 else 0 for n in nums]
print(clamped) # [0, 0, 0, 2, 4]
labels = ['even' if n % 2 == 0 else 'odd' for n in range(5)]
print(labels) # ['even', 'odd', 'even', 'odd', 'even']
signs = [(n, 'pos' if n > 0 else 'neg' if n < 0 else 'zero') for n in nums]
print(signs) # [(-3, 'neg'), (-1, 'neg'), (0, 'zero'), (2, 'pos'), (4, 'pos')]An if / else after the for is a filter (no else allowed); an if / else before the for is part of the output expression. Mixing them up is the easy syntax mistake to remember: filtering means 'maybe include this item', conditional output means 'always include this item but transform it differently'. The chained ternary in the third example shows how to map to three or more buckets in one comprehension, which is occasionally cleaner than a separate function but quickly becomes hard to read past three branches.
