List comprehension is a concise Python syntax that creates a new list by applying an expression to each item in an iterable — and optionally filtering items by a condition — all in a single line. It replaces the common pattern of creating an empty list, looping, and appending one element at a time.
What does list comprehension look like?
The syntax has three parts in a fixed order:
[expression for item in iterable if condition]
↑ ↑ ↑
What to add Where to loop Optional filter
Compare the two equivalent approaches:
# Traditional for-loop approach
squares = []
for n in range(1, 6):
squares.append(n ** 2)
print(squares) # [1, 4, 9, 16, 25]
# List comprehension — same result, one line
squares = [n ** 2 for n in range(1, 6)]
print(squares) # [1, 4, 9, 16, 25]
Both produce the same list. The comprehension is shorter, reads almost like English ("n squared, for n in 1 to 5"), and is generally considered more Pythonic.
How do you add a condition to filter the list?
Adding an if clause at the end keeps only the items that satisfy the condition:
# Keep only even numbers from 1 to 10
evens = [n for n in range(1, 11) if n % 2 == 0]
print(evens) # [2, 4, 6, 8, 10]
# Keep only words longer than 3 characters
words = ["cat", "elephant", "dog", "rhinoceros", "ox"]
long_words = [word for word in words if len(word) > 3]
print(long_words) # ['elephant', 'rhinoceros']
# Convert temperatures from Celsius to Fahrenheit, keeping only those above 100°F
celsius = [0, 20, 40, 60, 80, 100]
hot = [round(c * 9/5 + 32, 1) for c in celsius if c * 9/5 + 32 > 100]
print(hot) # [122.0, 140.0, 158.0, 176.0, 212.0]
The condition is evaluated for each item before the expression is applied — items that fail the condition are silently excluded.
How does list comprehension compare with a for loop?
| Criterion | For loop | List comprehension |
|---|---|---|
| Lines of code | 3–5 lines | 1 line |
| Readability | Clear for beginners | Concise once familiar |
| Performance | Slightly slower | Marginally faster (CPython optimises it) |
| Complexity | Handles any logic | Better for simple transformations |
| Debugging | Easy to add print statements | Harder to inspect intermediate steps |
For simple transformations and filters, list comprehension is preferred in professional Python. For complex multi-step logic, a regular loop is clearer — and clarity beats brevity.
What are common list comprehension patterns?
# Pattern 1: transform every element
upper_names = [name.upper() for name in ["alice", "bob", "carol"]]
# ["ALICE", "BOB", "CAROL"]
# Pattern 2: filter by condition
passing_marks = [mark for mark in [45, 72, 38, 91, 55] if mark >= 50]
# [72, 91, 55]
# Pattern 3: transform AND filter
long_upper = [name.upper() for name in ["ali", "robert", "jo"] if len(name) > 3]
# ["ROBERT"]
# Pattern 4: flatten a 2D list into 1D
matrix = [[1, 2], [3, 4], [5, 6]]
flat = [item for row in matrix for item in row]
# [1, 2, 3, 4, 5, 6]
# Pattern 5: create a list of tuples
pairs = [(x, y) for x in range(3) for y in range(3) if x != y]
# [(0,1),(0,2),(1,0),(1,2),(2,0),(2,1)]
Pattern 4 and 5 use nested comprehensions — an advanced technique. Treat them as an extension topic; for GCSE, patterns 1–3 are the core requirement.
How do you step through a list comprehension for a trace question?
Examiners sometimes ask you to trace or predict the output of a list comprehension. Work through it methodically:
- Identify the iterable: what values does the loop variable take?
- For each value, check the condition (if any). Discard if false.
- Apply the expression to each passing value.
- Collect the results into a list.
[x * 2 for x in range(5) if x % 2 != 0]
range(5) produces: 0, 1, 2, 3, 4
Filter x % 2 != 0:
x=0 → 0%2==0, reject
x=1 → 1%2!=0, keep → 1*2 = 2
x=2 → 2%2==0, reject
x=3 → 3%2!=0, keep → 3*2 = 6
x=4 → 4%2==0, reject
Result: [2, 6]
Frequently asked questions
When should I use list comprehension instead of a for loop?
Use list comprehension when you are building a new list by applying a simple transformation or filter to an existing iterable. It produces cleaner, more readable code for this specific pattern. Use a regular for loop when the logic inside the loop is complex, when you need to update multiple variables, or when you need to call a function with side effects on each iteration.
Can list comprehension work with strings?
Yes. Strings are iterables in Python, so you can iterate over their characters. [char.upper() for char in "hello"] produces ['H', 'E', 'L', 'L', 'O']. You can also filter: [char for char in "Hello World!" if char.isalpha()] keeps only letters.
Is list comprehension in the GCSE Computer Science specification?
List comprehension is a Python feature rather than a specification topic in its own right. AQA and OCR expect students to be comfortable with Python programming, and list comprehension is likely to appear in examination questions on lists and iteration. It is particularly useful in the programming project (non-examined assessment) as a way to write clean, efficient code.
What is the difference between a list comprehension and a generator expression?
A list comprehension [expr for x in iterable] creates the entire list immediately and stores it in memory. A generator expression (expr for x in iterable) — note round brackets — produces values one at a time on demand, using far less memory for large datasets. For GCSE, list comprehensions are the primary focus; generators are an A-level extension topic.
Build your Python comprehension skills — pun intended — with guided questions from Professor Turing at aitutors.me.