Comprehensions Competent¶
List comprehension¶
List comprehension in Comprehensions — what it is and when to use it.
# [expression for item in iterable if condition]
squares = [x**2 for x in range(10)]
evens = [x for x in range(20) if x % 2 == 0]
words = [w.upper() for w in sentence.split() if len(w) > 3]
Dict comprehension¶
Dict comprehension in Comprehensions — what it is and when to use it.
# {key_expr: value_expr for item in iterable}
scores = {"Alice": 95, "Bob": 87, "Charlie": 72}
passed = {k: v for k, v in scores.items() if v >= 80}
# {'Alice': 95, 'Bob': 87}
Set comprehension¶
Set comprehension in Comprehensions — what it is and when to use it.
Generator expression¶
Generator expression in Comprehensions — what it is and when to use it.
# Like list comp but with () — lazy evaluation
total = sum(x**2 for x in range(1000000)) # no list in memory
Nested comprehensions¶
Nested comprehensions in Comprehensions — what it is and when to use it.
# Flatten a matrix
matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
flat = [n for row in matrix for n in row]
# [1, 2, 3, 4, 5, 6, 7, 8, 9]
# Create a matrix
grid = [[0 for _ in range(3)] for _ in range(3)]
Readability limit
If a comprehension gets hard to read, use a regular loop. Comprehensions should clarify, not obfuscate.
Conditional expression inside the output¶
Conditional expression inside the output in Comprehensions — what it is and when to use it.
Put a ternary in the expression part to transform (not filter):
labels = ["even" if x % 2 == 0 else "odd" for x in range(4)]
print(labels) # ['even', 'odd', 'even', 'odd']
Filtering (if at the end) and transforming (if/else up front) can combine:
Invert / transform a dict¶
Invert / transform a dict in Comprehensions — what it is and when to use it.
scores = {"Alice": 95, "Bob": 87}
inverted = {v: k for k, v in scores.items()}
print(inverted) # {95: 'Alice', 87: 'Bob'}
Walrus operator in comprehensions¶
Walrus operator in comprehensions in Comprehensions — what it is and when to use it.
Reuse a computed value without recomputing it (Python 3.8+):
def expensive(x):
return x * x
results = [y for x in range(6) if (y := expensive(x)) > 10]
print(results) # [16, 25]
The classic nested-loop ordering gotcha¶
The classic nested-loop ordering gotcha — a key concept in Comprehensions.
for clauses read left to right, same as nested loops:
pairs = [(x, y) for x in [1, 2] for y in ["a", "b"]]
print(pairs) # [(1, 'a'), (1, 'b'), (2, 'a'), (2, 'b')]
Generator vs list memory¶
Generator vs list memory in Comprehensions — what it is and when to use it.
import sys
list_comp = [x for x in range(1000)]
gen_exp = (x for x in range(1000))
print(sys.getsizeof(list_comp) > sys.getsizeof(gen_exp)) # True
A generator holds one item at a time; the list holds all 1000.
Practice exercises¶
- Use a dict comprehension to invert a dictionary (swap keys and values).
- Use a nested list comprehension to generate a multiplication table.
- Use a generator expression with
sum()to calculate the sum of all primes below 10000. - Use the walrus operator in a comprehension to keep only values whose square root is an integer.
- Build a dict comprehension that maps each word in a sentence to its length.
💬 Discussion
Have a question about this topic? Found an error? Share your thoughts below.