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.