Comprehensions
The problem comprehensions solve
You’ve now written this shape of code several times in this module — build an empty collection, loop, and add to it:
This pattern — transform every item in a collection into a new collection — is extremely common, common enough that Python has dedicated syntax for it. A list comprehension does the same thing in one line:
Read it as: “tool.upper(), for every tool in tools.” The expression on
the left is what goes into the new list; the for on the right is where
each item comes from. This is genuinely different from anything in Java or
C++ — the closest analog most people know is JavaScript’s .map(), but
comprehensions are built into the language’s syntax rather than being a
method call.
Adding a filter
You can also filter which items get included, with an if at the end:
Read it as: “tool.upper(), for every tool in tools, if
len(tool) > 6.” The loop-and-append equivalent makes clear what’s being
compressed:
Same result, four lines compressed to one. This filtering if is different
from a ternary-style if/else inside the expression, which is covered next.
Conditional expression inside a comprehension
A different use of if can sit in the expression part instead, to choose
between two values — this always needs else too, unlike the filter
version above:
Every item is kept here (this isn’t filtering), just labeled differently.
The position of if is the tell: if before for picks between two
expressions per item; if after for filters which items are included
at all.
Dict comprehensions
Same idea, building a dict instead of a list — the syntax swaps [] for
{} and needs a key: value pair:
This replaces the manual tally-building pattern from Concept 3 in cases where you’re computing one value per item, rather than accumulating a running count. (The tally-counter pattern itself still needs the manual loop, since each iteration depends on the previous count — a comprehension builds each entry independently.)
Set comprehensions
Same again, with {} but no : — just an expression, like a list
comprehension but deduplicated automatically:
When not to use a comprehension
Comprehensions are for building a new collection from a transformation — not for side effects like printing, and not when the logic is complex enough that cramming it into one line hurts readability more than it helps:
# Fine — simple transformation
squares = [n ** 2 for n in range(5)]
# Bad practice — comprehension used for a side effect, not to build anything
[print(tool) for tool in tools] # works, but the resulting list is thrown away and unused
# Better as a plain loop — nothing is being built into a new collection
for tool in tools:
print(tool)What does [tool.upper() for tool in tools] produce?
Use a list comprehension with a filter if to pull out just the names of enabled tools.