Lesson 1 of 10
Module 3 covered list comprehensions. The same syntax builds dictionaries and sets, and handles more complex shapes.
Dict comprehensions
Curly braces with a key: value pair:
numbers = [1, 2, 3, 4]
squares = {n: n ** 2 for n in numbers}
print(squares)
Transforming an existing dictionary is the most common use:
prices = {"apple": 1.0, "banana": 0.5, "cherry": 3.0}
doubled = {name: price * 2 for name, price in prices.items()}
print(doubled)
cheap = {name: price for name, price in prices.items() if price < 2}
print(cheap)
flipped = {price: name for name, price in prices.items()}
print(flipped)
Two useful patterns — building a lookup table from records, and normalising keys:
people = [
{"id": 1, "name": "Ada"},
{"id": 2, "name": "Grace"},
]
by_id = {p["id"]: p["name"] for p in people}
print(by_id)
config = {"THEME": "dark", "Font": "mono"}
print({k.lower(): v for k, v in config.items()})
Set comprehensions
Same braces, no colon:
words = ["apple", "banana", "avocado", "blueberry"]
first_letters = {w[0] for w in words}
print(sorted(first_letters))
lengths = {len(w) for w in words}
print(sorted(lengths))
Duplicates disappear automatically — that's the point.
Conditional expressions inside
An if at the end filters. An if/else before the for transforms:
numbers = [1, 2, 3, 4, 5, 6]
print([n for n in numbers if n % 2 == 0])
print(["even" if n % 2 == 0 else "odd" for n in numbers])
The difference is worth internalising: a trailing if chooses which items to keep; a leading
if/else chooses what value each item becomes. You can combine both:
numbers = [1, 2, 3, 4, 5, 6]
print(["big" if n > 4 else "small" for n in numbers if n % 2 == 0])
Nested loops
Two for clauses read in the same order you'd write the nested loop:
pairs = [(x, y) for x in [1, 2] for y in ["a", "b"]]
print(pairs)
Flattening a nested list is the classic case:
matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
flat = [n for row in matrix for n in row]
print(flat)
evens = [n for row in matrix for n in row if n % 2 == 0]
print(evens)
You can also nest a comprehension inside a comprehension:
matrix = [[1, 2], [3, 4]]
doubled = [[n * 2 for n in row] for row in matrix]
print(doubled)
Know when to stop
Comprehensions are for building a collection from another one. Once you need multiple conditions, nested loops, and a transformation all at once, a plain loop is clearer:
matrix = [[1, 2, 3], [4, 5, 6]]
result = [n * 2 for row in matrix for n in row if n % 2 == 0 if n > 2]
print(result)
result = []
for row in matrix:
for n in row:
if n % 2 == 0 and n > 2:
result.append(n * 2)
print(result)
Both work. The second is easier to debug and easier to explain. Readability wins — that's the Pythonic instinct, and lesson 9.8 returns to it.
Try it yourself
Checkpoint
{k: v for ...}builds a dict;{x for ...}builds a set.- A trailing
iffilters; a leadingif/elsetransforms. - Multiple
forclauses read left to right, like nested loops. - Stop and use a loop when the comprehension stops being readable.
Questions about this lesson
Log in to ask a question.