Common pattern: take a list, transform each item, get a new list. Written explicitly:
numbers = [1, 2, 3, 4]
doubled = []
for n in numbers:
doubled.append(n * 2)
print(doubled) # [2, 4, 6, 8]4 lines for one transformation.
Python has a one-line version called a list comprehension:
doubled = [n * 2 for n in numbers]Same result, one line. Read it left-to-right: "a list of n * 2 for each n in numbers."
That's a lot of meaning packed in one line. When should I use it?
When the transformation is simple — one expression. If you'd write more than one line of work per iteration, use a regular for loop. Comprehensions are for transforms, not for general loops.
[expression for item in iterable]Read as: "a list of expression for each item in iterable."
numbers = [1, 2, 3, 4]
[n * 2 for n in numbers] # [2, 4, 6, 8]
[n ** 2 for n in numbers] # [1, 4, 9, 16]
[str(n) for n in numbers] # ['1', '2', '3', '4']Works on any iterable — strings, ranges, dict keys, set, even another comprehension's output:
[c.upper() for c in "abc"] # ['A', 'B', 'C']
[i for i in range(5)] # [0, 1, 2, 3, 4]if clause at the end[n for n in [1, 2, 3, 4, 5, 6] if n % 2 == 0]
# [2, 4, 6] — only even numbers keptYou can transform AND filter:
[n * 10 for n in [1, 2, 3, 4, 5] if n > 2]
# [30, 40, 50]If the body of the loop has more than one expression, or has side effects (print, append to a different list, conditional logic with else), use a regular for loop. Comprehensions reward clarity for one transformation per item; they punish complexity.
# Bad — comprehension as control flow
[print(n) for n in numbers] # works but builds a list of None for nothing
# Good — regular for loop
for n in numbers:
print(n)If you'd describe the operation as "a list of X for each Y", a comprehension reads cleanly. If you'd describe it as "go through each Y and do …", a regular for loop is clearer.
Create a free account to get started. Paid plans unlock all tracks.
Common pattern: take a list, transform each item, get a new list. Written explicitly:
numbers = [1, 2, 3, 4]
doubled = []
for n in numbers:
doubled.append(n * 2)
print(doubled) # [2, 4, 6, 8]4 lines for one transformation.
Python has a one-line version called a list comprehension:
doubled = [n * 2 for n in numbers]Same result, one line. Read it left-to-right: "a list of n * 2 for each n in numbers."
That's a lot of meaning packed in one line. When should I use it?
When the transformation is simple — one expression. If you'd write more than one line of work per iteration, use a regular for loop. Comprehensions are for transforms, not for general loops.
[expression for item in iterable]Read as: "a list of expression for each item in iterable."
numbers = [1, 2, 3, 4]
[n * 2 for n in numbers] # [2, 4, 6, 8]
[n ** 2 for n in numbers] # [1, 4, 9, 16]
[str(n) for n in numbers] # ['1', '2', '3', '4']Works on any iterable — strings, ranges, dict keys, set, even another comprehension's output:
[c.upper() for c in "abc"] # ['A', 'B', 'C']
[i for i in range(5)] # [0, 1, 2, 3, 4]if clause at the end[n for n in [1, 2, 3, 4, 5, 6] if n % 2 == 0]
# [2, 4, 6] — only even numbers keptYou can transform AND filter:
[n * 10 for n in [1, 2, 3, 4, 5] if n > 2]
# [30, 40, 50]If the body of the loop has more than one expression, or has side effects (print, append to a different list, conditional logic with else), use a regular for loop. Comprehensions reward clarity for one transformation per item; they punish complexity.
# Bad — comprehension as control flow
[print(n) for n in numbers] # works but builds a list of None for nothing
# Good — regular for loop
for n in numbers:
print(n)If you'd describe the operation as "a list of X for each Y", a comprehension reads cleanly. If you'd describe it as "go through each Y and do …", a regular for loop is clearer.