Python List Comprehensions Explained (Python Docs 5.1.3) | Syntax, Filtering, Nested Comprehensions & Beginner Guide
This page explains the official Python List Comprehensions documentation (Python Docs 5.1.3 and 5.1.4) in simple language. Learn how Python list comprehensions work, understand the syntax, filtering, nested comprehensions, multiple for clauses, and real examples. If official Python documentation feels confusing, this guide breaks every concept into beginner-friendly explanations with practical code examples. This guide covers the syntax, filtering with if, multiple for clauses, nested comprehensions, and the classic matrix transpose example.
By the end of this guide, you'll know when to use a list comprehension instead of a loop, how to filter and transform data in one line, and how nested comprehensions work โ plus the common mistakes that trip people up.
What is a Python List Comprehension? (Python Docs 5.1.3 Explained)
A list comprehension is a compact way to create a list โ in one line, without writing a full for loop and .append(). It reads almost like English: "give me X for each Y in Z."
They're faster to write and can be slightly faster to run in many cases. When used correctly, they can also make code shorter and more readable than the equivalent loop. The Python docs describe them as "a concise way to create lists" and they're one of the features that makes Python feel genuinely elegant.
List comprehensions provide a concise way to create lists. Common applications are to make new lists where each element is the result of some operations applied to each member of another sequence or iterable, or to create a subsequence of those elements that satisfy a certain condition.
List Comprehension Syntax โ Broken Down
The full syntax has four parts โ only the first two are required:
# The long way โ for loop + append
squares = []
for x in range(10):
squares.append(x**2)
# [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
# Same thing with map() + lambda
squares = list(map(lambda x: x**2, range(10)))
# The concise way โ list comprehension (most readable)
squares = [x**2 for x in range(10)]
# [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
List Comprehension vs For Loop โ When to Use Which
Comprehensions are better when you're building a new list from an existing one and the logic fits in one line. Loops are better when the logic is complex, has side effects, or needs multiple statements.
# Use a comprehension โ simple transformation
doubled = [x * 2 for x in range(5)]
# [0, 2, 4, 6, 8]
# Use a loop โ multiple operations, side effects
results = []
for x in range(5):
val = x * 2
print(f"Processing {x}") # side effect
if val > 0:
results.append(val)
# Use a comprehension โ filter + transform in one line
passing = [score for score in [45, 78, 32, 90, 55] if score >= 50]
# [78, 90, 55]
Filtering with if in Python List Comprehensions
Add an if clause at the end to filter which items make it into the new list. The if acts as a guard โ only items where the condition is True get processed.
vec = [-4, -2, 0, 2, 4]
# Filter: exclude negative numbers
[x for x in vec if x >= 0]
# [0, 2, 4]
# Transform + filter together
[x**2 for x in vec if x > 0]
# [4, 16]
Kiddo extra โ practical filtering patterns
# Keep only even numbers
evens = [x for x in range(20) if x % 2 == 0]
# [0, 2, 4, 6, 8, 10, 12, 14, 16, 18]
# Keep only strings longer than 3 chars
words = ["hi", "python", "is", "cool", "ok"]
long_words = [w for w in words if len(w) > 3]
# ['python', 'cool']
# Filter None values out
data = [1, None, 2, None, 3, 4, None]
clean = [x for x in data if x is not None]
# [1, 2, 3, 4]
# Keep passing scores and uppercase the names
students = [("Palak", 92), ("Arjun", 45), ("Sneha", 78)]
passed = [name.upper() for name, score in students if score >= 50]
# ['PALAK', 'SNEHA']
If-Else Conditions in List Comprehensions
List comprehensions can also use if-else conditions when you want to choose between two values while creating a new list. The placement is different from filtering โ the if-else goes before the for loop.
# Add grades based on scores
scores = [92, 45, 78, 30]
grades = [
"Pass" if score >= 50 else "Fail"
for score in scores
]
print(grades)
# ['Pass', 'Fail', 'Pass', 'Fail']
Filtering uses:
[x for x in items if condition]Conditional values use:
[value_if_true if condition else value_if_false for x in items]
Multiple for Clauses in One Comprehension
You can chain multiple for clauses โ they work just like nested loops. The leftmost for is the outer loop, the rightmost is the inner loop. The order matches the order you'd write them as nested loops.
# From the Python docs โ combine two lists where elements are not equal
[(x, y) for x in [1,2,3] for y in [3,1,4] if x != y]
# [(1, 3), (1, 4), (2, 3), (2, 1), (2, 4), (3, 1), (3, 4)]
# This is exactly equivalent to:
combs = []
for x in [1,2,3]:
for y in [3,1,4]:
if x != y:
combs.append((x, y))
# Same result
Note how the order of the for and if statements is the same in both the comprehension and the equivalent nested loop. If the expression is a tuple (e.g. (x, y)), it must be parenthesized.
[x, y for x in a for y in b] raises a SyntaxError. The correct form is [(x, y) for x in a for y in b].
All Python Docs Examples Explained
The Python docs ยง5.1.3 shows several patterns. Here's every one of them, with explanations:
vec = [-4, -2, 0, 2, 4]
# Double each value
[x*2 for x in vec]
# [-8, -4, 0, 4, 8]
# Filter: keep only non-negative
[x for x in vec if x >= 0]
# [0, 2, 4]
# Apply abs() to every element
[abs(x) for x in vec]
# [4, 2, 0, 2, 4]
# Call .strip() on each string โ removes whitespace
freshfruit = [' banana', ' loganberry ', 'passion fruit ']
[weapon.strip() for weapon in freshfruit]
# ['banana', 'loganberry', 'passion fruit']
# Create (number, square) tuples โ tuple MUST be parenthesized
[(x, x**2) for x in range(6)]
# [(0, 0), (1, 1), (2, 4), (3, 9), (4, 16), (5, 25)]
# This raises SyntaxError โ tuple not parenthesized:
# [x, x**2 for x in range(6)]
# Flatten a 2D list โ nested for clauses
vec = [[1,2,3], [4,5,6], [7,8,9]]
[num for elem in vec for num in elem]
# [1, 2, 3, 4, 5, 6, 7, 8, 9]
# Complex expressions and nested functions
from math import pi
[str(round(pi, i)) for i in range(1, 6)]
# ['3.1', '3.14', '3.142', '3.1416', '3.14159']
Nested List Comprehensions (Python Docs 5.1.4)
The initial expression in a list comprehension can itself be another list comprehension. This is called a nested list comprehension and is most commonly used for working with 2D data like matrices.
The initial expression in a list comprehension can be any arbitrary expression, including another list comprehension.
# A 3x4 matrix โ list of 3 lists, each of length 4
matrix = [
[1, 2, 3, 4],
[5, 6, 7, 8],
[9, 10, 11, 12],
]
# Transpose rows and columns with a nested list comprehension
[[row[i] for row in matrix] for i in range(4)]
# [[1, 5, 9], [2, 6, 10], [3, 7, 11], [4, 8, 12]]
for i in range(4) runs first, giving i = 0, 1, 2, 3. For each i, the inner [row[i] for row in matrix] collects the i-th element from every row โ which is a column.
Matrix Transposition โ The Complete Picture
The docs show three equivalent ways to transpose a matrix, from most manual to most Pythonic:
matrix = [
[1, 2, 3, 4],
[5, 6, 7, 8],
[9, 10, 11, 12],
]
# Approach 1 โ nested list comprehension (from the docs)
[[row[i] for row in matrix] for i in range(4)]
# [[1, 5, 9], [2, 6, 10], [3, 7, 11], [4, 8, 12]]
# Approach 2 โ equivalent nested for loop
transposed = []
for i in range(4):
transposed.append([row[i] for row in matrix])
# Approach 3 โ most Pythonic: zip() with unpacking (from the docs)
list(zip(*matrix))
# [(1, 5, 9), (2, 6, 10), (3, 7, 11), (4, 8, 12)]
list(zip(*matrix)) does the same transpose in one line. The * unpacks the matrix into separate arguments that zip() then zips column-by-column.
Common List Comprehension Mistakes
[x, x**2 for x in range(6)] raises SyntaxError. When the expression is a tuple, it must be wrapped in parentheses: [(x, x**2) for x in range(6)]. The Python docs call this out explicitly.
The order of for clauses in a comprehension matches the order of loops if you were to write them out. Outer loop first, inner loop second โ same as nested loops.
Filtering if goes at the end: [x for x in items if x > 0]. Conditional expressions (ternary) go in the expression position: [x if x > 0 else 0 for x in items]. These are different things and different syntax.
[print(x) for x in items] works but creates a list of None values nobody uses โ wasteful and confusing. If you want side effects, write a regular for loop.
Deeply nested or multi-condition comprehensions can become unreadable fast. If you have to think hard to understand it, break it into a loop or split it across variables. Readability is more valuable than brevity.
Python List Comprehension Interview Questions and Answers
[expression for item in iterable if condition]. The if part is optional. It's equivalent to a for loop with .append() but more concise and often more readable.[x for x in items] evaluates immediately and stores all values in memory. A generator expression (x for x in items) is lazy โ it computes values one at a time on demand. Use generators for large datasets where you don't need all values at once.[x**2 for x in range(1, 21) if x % 2 == 0] gives [4, 16, 36, 64, 100, 144, 196, 256, 324, 400]. The if x % 2 == 0 filters to even numbers only before squaring.[num for row in matrix for num in row]. The outer for row in matrix iterates over each sublist, and the inner for num in row iterates over each element. From the Python docs: [num for elem in vec for num in elem].[x, x**2 for x in range(6)] raises a SyntaxError. Python can't parse it correctly without parentheses around the tuple. The fix: [(x, x**2) for x in range(6)]. The Python docs call this out specifically.[[row[i] for row in matrix] for i in range(4)]. The inner comprehension collects each column, the outer builds the transposed rows..append() calls. But the difference is small for small lists. For very large datasets, a generator expression may be better if you don't need the full list in memory at once.Mini Project โ Student Report Card Generator
You've got a list of students with their names and raw scores across three subjects. Using only list comprehensions, build a report card: calculate each student's average, assign a grade, and filter out anyone who hasn't passed all three subjects.
This covers filtering, transformation, multi-value unpacking, and conditional expressions โ all the core comprehension patterns in one project.
[max(students, key=lambda s: s["scores"][i])["name"] for i in range(3)] โ which gives the top scorer for each of the three subjects in one line.
Python List Comprehensions FAQ
[expression for item in iterable]. It's a concise replacement for a for loop + append(). From the Python docs: "a concise way to create lists."if condition at the end: [x for x in items if x > 0]. Only items where the condition is True make it into the list. For a ternary (if/else in the result), put it in the expression: [x if x > 0 else 0 for x in items].[(x, y) for x in [1,2,3] for y in [3,1,4] if x != y] โ this is equivalent to nested for loops. The order of the for clauses matches the nesting order: leftmost is the outermost loop.[x, x**2 for x in range(6)] is a SyntaxError. The correct form is [(x, x**2) for x in range(6)]. The Python docs specifically call this out.[[row[i] for row in matrix] for i in range(4)]. For simple cases, the built-in zip(*matrix) is often cleaner.Lists ยท Tuples (5.3) ยท Dictionaries (5.5) ยท Sets (5.4) ยท Functions ยท While Loop