Writing your first list comprehension can feel like trying to write a sentence backwards. In a normal loop, you start with the source, then the condition, then the action. In a comprehension, the action comes first.
It breaks the linear thought process of "First do this, then do that."
But don't worry. You don't need to be a math wizard to learn this. You just need a system.
[!NOTE] The Cheat Code
- Expression: Logic from inside
.append()- Loop: Logic from
for ...- Filter: Logic from
if ...- Assemble:
[Expression Loop Filter]
Table of Contents
- The Mental Block
- The 3-Step Translation Method (Visualized)
- Level 1: The Basic Loop
- Level 2: Adding a Filter (If)
- Level 3: Logic Transformation (If-Else)
- Level 4: Nested Loops
- When You CANNOT Convert a Loop
- Practice Exercises
- Test Your Knowledge (Quiz)
The Mental Block
Why is this hard?
Standard Loop:
for item in collection:
output.append(expression)
The flow is: Loop -> Do I keep it? -> Append.
Comprehension:
[expression for item in collection]
The flow is: Append -> Loop -> Do I keep it?
You have to state the result before you state where it comes from. Let's fix this rewiring with a simple drag-and-drop method.
The 3-Step Translation Method (Visualized)
Whenever you want to write a comprehension, start by writing (or imagining) the for loop version.
for item in items: if check(item): res.append(expression)
|----------------| |-------------| |--------|
| | |
v v v
[ for item in items if check(item) ] [ expression ]
Wait, let's rearrange it:
[ expression for item in items if check(item) ]
^^^^^^^^^^ ^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^
STEP 1 STEP 2 STEP 3
Step 1: Identify the "Append" Payload
Look at your loop. What is inside the .append(...) brackets? That is your Expression.
Step 2: Identify the "Iterator"
Look at the top line. What comes after for and in? That is your Loop.
Step 3: Identify the "Gatekeeper"
Is there an if statement checking the item? That is your Filter.
Now, drop them into this template:
[ <Expression> <Loop> <Filter> ]
Level 1: The Basic Loop
The Goal: Double every number in a list.
The Old Way:
numbers = [1, 2, 3]
result = []
for x in numbers: # The Loop
result.append(x * 2) # The Expression
The Translation:
- Expression:
x * 2 - Loop:
for x in numbers - Filter: None
The Result:
[x * 2 for x in numbers]
See? We just took line 4 and put it before line 3.
Level 2: Adding a Filter (If)
The Goal: Keep only numbers greater than 5.
The Old Way:
numbers = [3, 8, 2, 10]
result = []
for x in numbers: # The Loop
if x > 5: # The Filter
result.append(x) # The Expression
The Translation:
- Expression:
x - Loop:
for x in numbers - Filter:
if x > 5
The Result:
# [Expr Loop Filter]
[x for x in numbers if x > 5]
Important: The filter always goes at the END.
Level 3: Logic Transformation (If-Else)
The Goal: Label numbers as "Even" or "Odd".
The Old Way:
numbers = [1, 2]
result = []
for x in numbers:
if x % 2 == 0:
result.append("Even")
else:
result.append("Odd")
Wait! This doesn't fit our template easily because there are two append statements. How do we fix this?
The Fix: Turn the logic into a single expression first using Python's ternary operator.
# Mental Step: Rewrite the logic
val = "Even" if x % 2 == 0 else "Odd"
result.append(val)
Now we can translate:
- Expression:
"Even" if x % 2 == 0 else "Odd" - Loop:
for x in numbers
The Result:
["Even" if x % 2 == 0 else "Odd" for x in numbers]
Level 4: Nested Loops
The Goal: Flatten a matrix [[1,2], [3,4]].
The Old Way:
matrix = [[1, 2], [3, 4]]
result = []
for row in matrix: # Outer Loop
for num in row: # Inner Loop
result.append(num) # Expression
The Translation: Just stack the loops in the same order.
- Expression:
num - Loop 1:
for row in matrix - Loop 2:
for num in row
The Result:
[num for row in matrix for num in row]
When You CANNOT Convert a Loop
Not every loop should be a comprehension. Here are 3 signs you should stop trying:
1. The Loop has Side Effects If your loop prints something, saves a file, or modifies a global variable, do not use a comprehension. Comprehensions are for creating lists, not doing actions.
2. Complex elif Chains
If you have if... elif... elif... else, the ternary operator in the comprehension will look like a nightmare.
# Don't do this
[x if c1 else y if c2 else z for ...]
3. Breaking the Loop
You cannot break out of a comprehension early. It runs to completion. If you need to stop when you find a match, use a generator or a standard loop.
Practice Exercises
Grab a pen or open your IDE. Try to convert these loops.
Exercise 1: Basic Math
res = []
for i in range(5):
res.append(i + 10)
Exercise 2: Filter Strings
names = ["Al", "Bo", "Cy"]
res = []
for name in names:
if len(name) > 2:
res.append(name)
Exercise 3: Clean Data
data = [" 1 ", " 2 "]
res = []
for d in data:
res.append(int(d.strip()))
Solutions
[i + 10 for i in range(5)][name for name in names if len(name) > 2][int(d.strip()) for d in data]
Test Your Knowledge
Conclusion
Writing list comprehensions is a muscle memory skill. The first 10 times, you will have to pause and rearrange the logic in your head. By the 50th time, you won't even see the for loop anymore; you'll just see the data transformation.
Next Steps:
- Now that you can write them, learn to write complex ones: If-Else Transformation Guide.
- Avoid the pitfalls: Common Mistakes for Beginners.