List & Set Comprehensions
In short: a comprehension is a loop that builds a new collection in
one expression: [expr for item in iterable if cond] makes a list,
{expr for item in iterable if cond} makes a set, and {key: value for item in iterable if cond} makes a dict. The if is optional and just skips items.
Read it in English, left to right: "give me expr, for every item in
iterable, where cond." A comprehension never leaks its loop variable into
the surrounding scope — unlike a plain for loop, which does. Past one for
and one if, most comprehensions stop being easier to read than a written-out
loop — that's the line to stop at.
![Two lanes doing the same job: the top lane is a factory line — raw items enter, a gate keeps only the ones passing a test, a stamping tool transforms what's left, finished items exit — labelled "[transform for item in items if test]"; the bottom lane is the same four steps drawn as a plain for-loop with an if and an append, taking up four times the space](/api/assets/python/assets/1746396fd9154cde.png)
Build a festival price list
A café wants a quick list of festival prices — only for items under ₹100, each one 20% off. The loop version and the comprehension build the exact same list:
Read the comprehension as three parts, always in this order: what to keep
(round(p * 0.8, 2)), where from (for p in prices), which ones
(if p < 100). Leave off the if and every item survives, just transformed.
De-duplicate customer emails
A signup form collects emails with mixed case and stray spaces. A set comprehension both normalises and drops duplicates in one line, because a set can never hold the same value twice:
Three inputs, two customers — "Asha@mail.com" and "asha@MAIL.com " normalise to the same string, so the set keeps only one. A list comprehension here would keep all three, because a list allows repeats.
words = ["apple", "apricot", "banana", "blueberry"]
by_letter = {w[0]: w for w in words}
print(by_letter)Menu name → price lookup
Two parallel lists — names and prices, same order — become one dict with
zip, which pairs them up position by position:
zip(names, prices) hands out ("Tea", 20), then ("Coffee", 30), then
("Sandwich", 60) — the comprehension's for name, price in ... unpacks
each pair as it arrives, same as it would in a plain for loop.
Where a comprehension stops paying off
A matrix of daily orders per stall needs flattening into one list. One for
per level of nesting, read left to right, outermost first:
matrix = [[1, 2], [3, 4], [5]]
flat = [x for row in matrix for x in row]
print(flat)That's the limit worth knowing: one for plus a nested for is still
readable. Add a second if, or nest a comprehension inside another one's
expression, and a written-out loop with named steps gets easier to debug and
to read — don't force everything into one line.
A comprehension's loop variable is also its own: it never escapes, unlike a
plain for loop's variable (lesson 1).
Quick practice
scores = [55, 90, 38, 72]
passed = [s for s in scores if s >= 40]
print(passed, len(scores))Fix the condition so only orders under ₹100 remain.
fruits = ["fig", "kiwi", "apple", "pear"]
lengths = {len(f) for f in fruits}
print(sorted(lengths))matrix = [[1, 2, 3], [4, 5, 6]]
totals = [sum(row) for row in matrix]
print(totals)🎯 Your turn
Write veg_menu(items). Each item is a dict with "name", "price" and
"veg". Return a dict comprehension: {name: discounted price} for
only the vegetarian items, each price cut by 10% and rounded to 2
decimals.
veg_menu([{"name": "Paneer Wrap", "price": 120, "veg": True}])→{"Paneer Wrap": 108.0}- Non-veg items don't appear in the result at all.
Hint: {item["name"]: round(item["price"] * 0.9, 2) for item in items if item["veg"]} — one line, all three parts of a comprehension.
Press ▶ Run, try the Live App chips, then ✓ Check. After that, the practice set below goes from a filtered list to a full dict pipeline.
