Mental model: Think of a list comprehension as an assembly line with two stations: a filter and a transformer. The filter checks each item; if it passes, the transformer reshapes it into something new. You never see items that fail the check.
The basic form
# Old way
squares = []
for n in range(5):
squares.append(n * n)
print(squares) # [0, 1, 4, 9, 16]
# Comprehension way
squares = [n * n for n in range(5)]
print(squares)The pattern is
[expression for item in iterable]. Read it right-to-left: take each item from the iterable, compute the expression, and collect the results into a new list. No .append() needed.Filtering with if
# Keep only even numbers, then square them
even_squares = [n * n for n in range(10) if n % 2 == 0]
print(even_squares)The
if clause acts as a filter. Items that fail the test are skipped entirely — they never reach the expression part.When to use one over the other
nums = [1, 2, 3]
data = [{'name': 'ada'}, 'not a dict', {'id': 7}]
# Clear as a comprehension
doubles = [x * 2 for x in nums]
# Harder to read — a plain loop is fine here
result = []
for item in data:
if isinstance(item, dict) and 'name' in item:
result.append(item['name'].upper())