A comprehension builds a new list (or dict) from an existing sequence, in a single expression — it's a compact alternative to a for loop that only exists to .append() to a list.
squares = []
for n in range(1, 6):
squares.append(n * n)
# squares is [1, 4, 9, 16, 25]
squares = [n * n for n in range(1, 6)]
# [1, 4, 9, 16, 25]
Read it as: "n * n, for n in range(1, 6)" — the expression on the left (n * n) is computed once for every value the loop on the right produces, and the results are collected into a new list automatically.
Append an if to only include some elements:
evens = [n for n in range(10) if n % 2 == 0]
# [0, 2, 4, 6, 8]
This is equivalent to:
evens = []
for n in range(10):
if n % 2 == 0:
evens.append(n)
Same idea, but building a dict instead of a list — use {key_expr: value_expr for ... }:
squares_by_n = {n: n * n for n in range(1, 6)}
# {1: 1, 2: 4, 3: 9, 4: 16, 5: 25}
Comprehensions shine for simple "transform every element" or "filter some elements" logic. If the body of your loop needs several steps, multiple conditions, or side effects (like printing), a regular for loop is usually clearer — comprehensions are a readability improvement over a loop, not a rule you must follow everywhere. You already know how to write the loop version of everything in this lesson; the comprehension is just a shorter way to say the same thing once the pattern feels natural.