Beyond lists
Programs constantly need lookup tables (name → value) and deduplicated collections, and building them item by item is boilerplate. Dict and set comprehensions produce both in one line from anything you can loop over.
You built dictionaries key by key in Python for Beginners: d[key] = value inside a loop. Comprehensions cover that too. Swap the square brackets for curly braces and write a key: value pair up front:
lengths = {word: len(word) for word in words}Drop the colon and you get a set comprehension instead, a collection of unique values with no order:
firsts = {word[0] for word in words}One symbol changes the container:
| Brackets | Front part | Builds |
|---|---|---|
[expr ...] | one value | list |
{k: v ...} | pair with colon | dict |
{expr ...} | one value | set |
A lookup table and a set of initials
The dict comprehension produces one entry per word, while the set collects only the distinct first letters. Sets have no defined order, so the code sorts the set before printing to keep the output predictable.
words = ["apple", "avocado", "banana", "blueberry", "cherry"] lengths = {word: len(word) for word in words} print(lengths) firsts = {word[0] for word in words} print(sorted(firsts))
Output
{'apple': 5, 'avocado': 7, 'banana': 6, 'blueberry': 9, 'cherry': 6}
['a', 'b', 'c']Five words went in and the dict has five entries, but the set has only three, because avocado and apple share an initial and so do banana and blueberry.
Adding tax to every price
prices.items() yields (name, price) pairs, and a comprehension can unpack those pairs right in the for clause. That makes rebuilding a dict with the same keys and adjusted values a one-liner.
prices = {"tea": 3.5, "coffee": 4.25, "cocoa": 5.0}
with_tax = {name: round(p * 1.1, 2) for name, p in prices.items()}
print(with_tax)Output
{'tea': 3.85, 'coffee': 4.68, 'cocoa': 5.5}The front part is name: round(p * 1.1, 2), which is a key, a colon, then a value. Those curly braces plus the colon are exactly what make this a dict comprehension rather than a set comprehension. round(value, 2) trims the floating-point result to two decimal places, which is what you want any time the numbers represent money.
Nested comprehensions
A comprehension can hold two for clauses. They read exactly like nested loops, outer loop first:
pairs = [(x, y) for x in [1, 2] for y in ["a", "b"]] # [(1, 'a'), (1, 'b'), (2, 'a'), (2, 'b')]
The classic use is flattening a list of lists into one flat list:
grid = [[1, 2], [3, 4], [5, 6]] flat = [cell for row in grid for cell in row] # [1, 2, 3, 4, 5, 6]
Read it as: for each row in grid, for each cell in that row, take cell. If you need three levels or heavy logic, go back to real loops. Readability wins.
Flattening a list of lists
Rows of different lengths flatten just as cleanly as a rectangular grid, because the inner loop simply runs as many times as the current row is long.
grid = [[1, 2, 3], [4, 5], [6]] flat = [cell for row in grid for cell in row] print(flat)
Output
[1, 2, 3, 4, 5, 6]
Read the for clauses left to right, in the same order you would write nested loops: for row in grid is the outer loop, for cell in row is the inner one, and the value kept on each innermost pass is cell. Six cells spread across three rows come out as one flat list of six.
Braces alone do not make a dict
To map each number in nums = [1, 2, 3] to its double, the comprehension is {n: n * 2 for n in nums}, which builds {1: 2, 2: 4, 3: 6}.
A dict comprehension needs curly braces and a key: value pair separated by a colon. Writing {n * 2 for n in nums} has the braces but no colon, so Python reads it as a set comprehension and builds {2, 4, 6} instead. The colon is the whole difference between a lookup table and a bag of unique values.
Sets deduplicate as they build
{len(w) for w in ["hi", "to", "sun", "me"]} produces a set holding 2 items. The lengths computed along the way are 2, 2, 3, and 2, but a set stores each value only once, so the finished result is {2, 3}.
That dedup-for-free behavior is the main reason to reach for a set comprehension. When the thing you actually want to know is which distinct values appear in some data, a set comprehension answers it in one line, with no membership checks and no manual if value not in seen bookkeeping.