Script Valley
Python: Complete Language Course
Data StructuresLesson 2.5

Python list comprehensions and generators

list comprehension syntax, conditional comprehension, nested comprehension, generator expressions, memory efficiency, when to use each

List Comprehensions

A list comprehension builds a list in one readable line. It replaces a for-loop-plus-append pattern and is typically faster because Python optimises it internally.

# equivalent patterns:
squares_loop = []
for n in range(1, 6):
    squares_loop.append(n ** 2)

squares = [n ** 2 for n in range(1, 6)]
# [1, 4, 9, 16, 25]

With a Condition

evens = [n for n in range(20) if n % 2 == 0]
# [0, 2, 4, 6, ..., 18]

words = ["hello", "", "world", ""]
clean = [w.upper() for w in words if w]
# ['HELLO', 'WORLD']

Generator Expressions

Replace square brackets with parentheses to get a generator. A generator yields items lazily — it does not build the whole list in memory. Use generators when processing large datasets or when you only need to iterate once.

gen = (n ** 2 for n in range(1_000_000))
print(next(gen))  # 0  — only one item computed

total = sum(n ** 2 for n in range(1000))  # no list created

Avoid nested comprehensions deeper than two levels — they become hard to read. Use explicit loops for complex transformations.

List comprehensions are considered more Pythonic than map/filter for most use cases because they are easier to read and extend. However, do not use them for side effects — if the purpose of the loop is to print or mutate something rather than collect results, use a regular for loop. Generator expressions are drop-in replacements for list comprehensions in any context that only needs to iterate once — sum(), max(), any(), and all() all accept generators directly, saving memory when the dataset is large.