Comprehensions and Generators
Experienced Python code rarely builds a list with a manual loop when it can build one in a single, readable expression instead. This lesson covers the idioms that separate beginner Python from professional Python.
List comprehensions
squares = [n ** 2 for n in range(10)]
even_squares = [n ** 2 for n in range(10) if n % 2 == 0]
names = [student["name"] for student in students]
Read a comprehension the same way you’d read the equivalent loop: “for each n in range(10), keep n ** 2, but only if n % 2 == 0.” It’s the same logic as a for loop with an if and an append() call, just compressed into one line — and once you’re used to reading them, they’re actually faster to understand than the multi-line version.
Dict and set comprehensions
scores = {student["name"]: student["score"] for student in students}
unique_courses = {student["course"] for student in students}
The syntax follows the same pattern as list comprehensions, just with {} instead of [], and a key: value pair for dictionaries instead of a single expression.
Generators — lazy evaluation
def count_up_to(n):
i = 1
while i <= n:
yield i
i += 1
for number in count_up_to(5):
print(number)
A generator produces values one at a time, on demand, instead of building the whole list in memory upfront. This becomes essential once you’re processing large files or data streams that wouldn’t fit comfortably in memory as a full list. yield is what turns a normal function into a generator — the function pauses at yield, hands back one value, and resumes exactly where it left off the next time it’s asked for another.
Generator expressions
total = sum(n ** 2 for n in range(1000000))
Drop the square brackets from a list comprehension and you get a generator expression — it computes each value lazily rather than building a million-item list in memory first, which matters a great deal at that scale.
When not to use a comprehension
If the logic inside the loop needs more than one line, or involves multiple conditions that would make the comprehension hard to read in one glance, a regular for loop is the better, more maintainable choice. Comprehensions should make code clearer, not more clever for its own sake.