Python by Structure: List Comprehensions and Their Hidden Complexity
Source: Dev.to
Introduction
Timothy was refactoring some data processing code when he hit a comprehension he couldn’t understand.
“Margaret, someone wrote this comprehension and I can’t figure out what it does. It’s all on one line and my brain just… stops.”
Margaret looked at the code:
result = [item for sublist in data for item in sublist if item > 0 if item % 2 == 0]
“Ah,” Margaret said. “That’s a comprehension that’s crossed the line from clever to confusing. Let me show you what’s actually happening here.”
The Problem: Comprehensions Gone Wrong
“Comprehensions are powerful,” Margaret explained, “but they can become write‑only code. When you nest loops and stack filters, the execution order isn’t what most people expect.”
Timothy nodded. “I thought comprehensions were supposed to make code more readable. This is the opposite.”
Basic Comprehension
numbers = [1, 2, 3, 4, 5]
squares = [n * n for n in numbers]
English View
Set numbers to [1, 2, 3, 4, 5].
Set squares to:
List comprehension: n * n
For each n in numbers
“This is clear,” Margaret said. “You’re creating a new list by squaring each number.”
Adding Filters
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
even_squares = [n * n for n in numbers if n % 2 == 0]
English View
Set numbers to [1, 2, 3, 4, 5, 6, 7, 8, 9, 10].
Set even_squares to:
List comprehension: n * n
For each n in numbers
If n % 2 == 0
Result:
[4, 16, 36, 64, 100]
Multiple Filters
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
result = [n for n in numbers if n > 3 if n % 2 == 0]
English View
Set numbers to [1, 2, 3, 4, 5, 6, 7, 8, 9, 10].
Set result to:
List comprehension: n
For each n in numbers
If n > 3
If n % 2 == 0
“Two
ifstatements in a row—does that mean OR or AND?”
Both if clauses are combined with AND logic, equivalent to if n > 3 and n % 2 == 0.
Result:
[4, 6, 8, 10]
Nested Loops
matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
flat = [item for row in matrix for item in row]
English View
Set matrix to [[1, 2, 3], [4, 5, 6], [7, 8, 9]].
Set flat to:
List comprehension: item
For each row in matrix
For each item in row
Equivalent loop:
flat = []
for row in matrix:
for item in row:
flat.append(item)
Result:
[1, 2, 3, 4, 5, 6, 7, 8, 9]
Combining Nested Loops and Filters
data = [[1, -2, 3], [4, -5, 6], [7, 8, -9]]
result = [item for sublist in data for item in sublist if item > 0 if item % 2 == 0]
English View
Set data to [[1, -2, 3], [4, -5, 6], [7, 8, -9]].
Set result to:
List comprehension: item
For each sublist in data
For each item in sublist
If item > 0
If item % 2 == 0
Expanded version:
result = []
for sublist in data: # First For
for item in sublist: # Second For
if item > 0: # First If
if item % 2 == 0: # Second If
result.append(item)
Result:
[4, 6, 8]
When Comprehensions Become Too Complex
Guidelines
Use comprehensions when:
- The logic fits comfortably on one line
- The transformation is simple and obvious
- You have at most one level of nesting
- Filters are straightforward
Avoid comprehensions when:
- You need nested loops with complex conditions
- The logic requires multiple steps
- Reading it aloud doesn’t make immediate sense
- You’re tempted to add comments explaining it
A more readable rewrite of the complex example:
# More readable version
result = []
for sublist in data:
for item in sublist:
if item > 0 and item % 2 == 0:
result.append(item)