Use a list comprehension to build a new list from any iterable in one readable expression. Python’s syntax is documented in the official documentation, and the feature originated in PEP 202.
Method 1: Create a list with a basic comprehension
Step 1: Declare a source iterable.
nums = [2, 3, 4, 5]
Step 2: Write a comprehension using the pattern [expression for item in iterable]
.
squares = [n * n for n in nums]
print(squares) # [4, 9, 16, 25]
Step 3: Keep the original list unchanged.
print(nums) # [2, 3, 4, 5]
Method 2: Filter items with an if
clause
Step 1: Add a trailing condition to include only matching elements.
nums = range(10)
evens = [n for n in nums if n % 2 == 0]
print(evens) # [0, 2, 4, 6, 8]
Step 2: Use any iterable (lists, tuples, sets, generators).
letters = ("a", "b", "c", "aa", "bb")
filtered = [s for s in letters if len(s) == 1]
print(filtered) # ['a', 'b', 'c']
Method 3: Transform conditionally with an inline if-else
Step 1: Place a conditional expression before the for
to choose each output value.
temps = [12, -3, 18, -1]
non_negative = [t if t >= 0 else 0 for t in temps]
print(non_negative) # [12, 0, 18, 0]
Step 2: Keep filtering separate from transforming if you need both.
# Filter positives, then transform.
positives_squared = [t * t for t in temps if t > 0]
print(positives_squared) # [144, 324]
Method 4: Combine multiple loops and flatten nested data
Step 1: Chain for
clauses to generate combinations.
xs = [1, 2]
ys = ["a", "b", "c"]
pairs = [(x, y) for x in xs for y in ys]
print(pairs) # [(1, 'a'), (1, 'b'), (1, 'c'), (2, 'a'), (2, 'b'), (2, 'c')]
Step 2: Flatten a list of lists by iterating rows, then values.
grid = [[1, 2], [3, 4], [5, 6]]
flat = [v for row in grid for v in row]
print(flat) # [1, 2, 3, 4, 5, 6]
Method 5: Stream large results with a generator expression
Step 1: Replace brackets with parentheses to avoid building a full list in memory.
gen = (n * n for n in range(1_000_000)) # generator expression
Step 2: Consume the generator with a function like sum()
.
total = sum(n for n in range(1_000_000))
print(total)
Why it matters: generator expressions are evaluated lazily, which keeps memory usage low on huge datasets. See the original design note in PEP 289.
Method 6: Prefer built-ins over complex comprehensions
Step 1: Use zip()
for transposition instead of a deeply nested expression.
matrix = [
[1, 2, 3],
[4, 5, 6],
]
transposed = list(zip(*matrix))
print(transposed) # [(1, 4), (2, 5), (3, 6)]
Step 2: Choose a loop if the comprehension would span multiple lines or include side effects.
items = [" apple", "banana ", " pear "]
cleaned = []
for s in items:
t = s.strip()
cleaned.append(t)
print(cleaned) # ['apple', 'banana', 'pear']
Method 7: Compare to the equivalent for
loop
Step 1: Initialize the output list when using a traditional loop.
nums = [1, 2, 3, 4]
doubled = []
Step 2: Append inside the loop and keep logic explicit.
for n in nums:
doubled.append(n * 2)
print(doubled) # [2, 4, 6, 8]
Step 3: Use the comprehension version when it’s shorter and just as clear.
doubled_fast = [n * 2 for n in nums]
print(doubled_fast) # [2, 4, 6, 8]
Quick patterns you’ll reuse
- Map values:
[f(x) for x in data]
. - Filter values:
[x for x in data if keep(x)]
. - Conditional outputs:
[a(x) if test(x) else b(x) for x in data]
. - Flatten nested lists:
[y for row in rows for y in row]
.
Reference the syntax and nuances in the official documentation as you practice.
That’s it—use comprehensions for compact, readable transformations, switch to generator expressions for very large outputs, and fall back to clear loops when logic gets busy.
Member discussion