Python List Comprehension: Syntax, Examples and When to Avoid It
Learn Python list comprehension step by step: build, filter and transform lists in one line, see measured timings against loops, and know when a plain for loop reads better.
- The pattern is
[expression for item in iterable if condition]. - Put a plain
ifat the end to filter, and anif-elseat the front to choose between two values. - In our test a comprehension ran about 37% faster than a loop with
append. - Switch to a generator expression for huge data, and to a normal loop when the logic needs more than one clear step.
A Python list comprehension builds a new list from any iterable in a single readable line. Instead of creating an empty list, looping and calling append, you describe the result you want.
This guide goes from the basic pattern to filters, nested loops and timings we measured ourselves. If Python is new to you, start with our Python tutorial for beginners and keep a clean setup with the virtual environment guide.
Python list comprehension syntax
Read it from left to right: the expression says what each new item looks like, the for part says where items come from.
squares = [x * x for x in range(6)]
print(squares) # [0, 1, 4, 9, 16, 25]
names = [" Hi ", " QA "]
clean = [n.strip().lower() for n in names]
print(clean) # ['hi', 'qa']
The same result with a loop needs three more lines. That saving is the whole point, as long as the line stays easy to read.
Filter items with a condition
Add an if after the loop to keep only the items that pass.
evens = [x for x in range(10) if x % 2 == 0]
print(evens) # [0, 2, 4, 6, 8]
Python list comprehension with if-else
When you want a value for every item, put the if-else before the for. This is the part most beginners get wrong, because a trailing else is a syntax error.
labels = ["even" if x % 2 == 0 else "odd" for x in range(4)]
print(labels) # ['even', 'odd', 'even', 'odd']
Rule of thumb: an if at the end removes items, an if-else at the start changes items. The list length stays the same with if-else.
Nested loops and flattening
Several for clauses read in the same order as nested loops. Use them to flatten a list of lists or to pair values.
matrix = [[1, 2, 3], [4, 5, 6]]
flat = [n for row in matrix for n in row]
print(flat) # [1, 2, 3, 4, 5, 6]
pairs = [(x, y) for x in range(1, 3) for y in "ab"]
print(pairs) # [(1, 'a'), (1, 'b'), (2, 'a'), (2, 'b')]
To transpose the matrix, nest a comprehension inside another: [[r[i] for r in matrix] for i in range(3)] gives [[1, 4], [2, 5], [3, 6]]. Two levels is the practical limit before readability drops.
Dictionary, set and generator forms
Change the brackets and the same idea builds other types.
lengths = {w: len(w) for w in ["pip", "venv", "uv"]} # {'pip': 3, 'venv': 4, 'uv': 2}
unique = {len(w) for w in ["pip", "venv", "uv", "git"]} # {2, 3, 4}
total = sum(x * x for x in range(1_000_000)) # generator, no list
Compare the types themselves in our guide to lists, tuples, sets and dictionaries.
Speed and memory: what we measured
We timed each version on Python 3.13.6 with 100,000 integers, taking the best of five runs. Your numbers will differ, but the order is stable.
| Task | Time |
|---|---|
Loop with append (double each item) |
5.18 ms |
| List comprehension (double each item) | 3.25 ms |
list(map(lambda ...)) |
6.50 ms |
| Filter evens with a loop | 3.62 ms |
| Filter evens with a comprehension | 3.43 ms |
A comprehension beats the append loop clearly, while the gap shrinks when most of the time goes to the condition. On memory, a list of one million doubled integers took about 8.4 MB, while the matching generator object was 200 bytes, because it produces values one at a time.
When not to use a list comprehension
- You only need side effects such as printing or saving. Use a normal loop; a comprehension would build a useless list.
- The logic has several steps. If you need a second variable or a
try, write a loop or a small function. - The data is huge. Use a generator expression so Python never holds the full list in memory.
- It needs more than two
forclauses. Split it into named steps for the next reader.
Final thoughts
Use a Python list comprehension when one short line says exactly what you mean, and a loop when it does not. Start with the basic pattern, add one filter, then try the if-else form until the order feels natural.
Frequently asked questions
What is a list comprehension in Python?
It is a compact way to create a list by applying an expression to each item of an iterable, with an optional condition to filter items.
How do I use if-else in a list comprehension?
Put the conditional expression before the for clause, for example ["even" if x % 2 == 0 else "odd" for x in nums]. A plain filter uses a single if after the loop.
Is a list comprehension faster than a for loop?
Usually yes. In our test with 100,000 items it ran about 37% faster than a loop that calls append, but readability should decide first.
What is the difference between a list comprehension and a generator expression?
A list comprehension builds the whole list in memory at once. A generator expression uses parentheses and produces one value at a time, which saves memory on large data.
Can I nest list comprehensions?
Yes, for flattening or transposing a matrix. Keep it to two levels, and switch to a loop if it becomes hard to read.
Keep learning
Need help with testing, WordPress or SEO?
We help teams ship better software and grow their sites. Tell us what you are working on and we will suggest a clear next step.