Comprehensions are Python's concise way to create collections. Here's how to use them effectively.

List Comprehensions

Basic syntax:

# [expression for item in iterable]
squares = [x**2 for x in range(5)]  # [0, 1, 4, 9, 16]

With condition:

# [expression for item in iterable if condition]
evens = [x for x in range(10) if x % 2 == 0]  # [0, 2, 4, 6, 8]

Replacing Loops

Before:

result = []
for x in range(10):
    if x % 2 == 0:
        result.append(x**2)

After:

result = [x**2 for x in range(10) if x % 2 == 0]  # [0, 4, 16, 36, 64]

Dictionary Comprehensions

# {key: value for item in iterable}
squares = {x: x**2 for x in range(5)}
# {0: 0, 1: 1, 2: 4, 3: 9, 4: 16}
 
# Swap keys and values
original = {"a": 1, "b": 2, "c": 3}
swapped = {v: k for k, v in original.items()}
# {1: 'a', 2: 'b', 3: 'c'}
 
# Filter while transforming
prices = {"apple": 1.50, "banana": 0.75, "cherry": 3.00}
expensive = {k: v for k, v in prices.items() if v > 1}
# {'apple': 1.5, 'cherry': 3.0}

Set Comprehensions

# {expression for item in iterable}
unique_lengths = {len(word) for word in ["apple", "banana", "cherry", "date"]}
# {5, 6, 4}

Generator Expressions

Like list comprehensions, but lazy:

# (expression for item in iterable)
squares_gen = (x**2 for x in range(1000000))
 
# Doesn't compute until iterated
for square in squares_gen:
    if square > 100:
        break

Memory efficient—doesn't create the full list:

# Memory intensive
sum([x**2 for x in range(1000000)])
 
# Memory efficient
sum(x**2 for x in range(1000000))

Nested Comprehensions

Flatten a matrix:

matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
flat = [num for row in matrix for num in row]
# [1, 2, 3, 4, 5, 6, 7, 8, 9]

Create a matrix:

matrix = [[i * j for j in range(1, 4)] for i in range(1, 4)]
# [[1, 2, 3], [2, 4, 6], [3, 6, 9]]

Cartesian product:

pairs = [(x, y) for x in [1, 2, 3] for y in ['a', 'b']]
# [(1, 'a'), (1, 'b'), (2, 'a'), (2, 'b'), (3, 'a'), (3, 'b')]

Multiple Conditions

# AND condition
result = [x for x in range(100) if x % 2 == 0 if x % 3 == 0]
# [0, 6, 12, 18, 24, ...]
 
# Same as
result = [x for x in range(100) if x % 2 == 0 and x % 3 == 0]

Conditional Expressions

# expression if condition else expression
labels = ["even" if x % 2 == 0 else "odd" for x in range(5)]
# ['even', 'odd', 'even', 'odd', 'even']
 
# Clamp values
numbers = [1, 5, 10, 15, 20]
clamped = [min(max(x, 5), 15) for x in numbers]
# [5, 5, 10, 15, 15]

Practical Examples

Parse CSV data

lines = ["alice,25", "bob,30", "carol,35"]
users = [{"name": name, "age": int(age)} 
         for line in lines 
         for name, age in [line.split(",")]]

Filter and transform

data = [{"name": "Alice", "score": 85},
        {"name": "Bob", "score": 92},
        {"name": "Carol", "score": 78}]
 
high_scorers = [d["name"] for d in data if d["score"] >= 80]
# ['Alice', 'Bob']

Word frequency

text = "the quick brown fox jumps over the lazy dog"
words = text.lower().split()
freq = {word: words.count(word) for word in set(words)}

Transpose matrix

matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
transposed = [[row[i] for row in matrix] for i in range(len(matrix[0]))]
# [[1, 4, 7], [2, 5, 8], [3, 6, 9]]

File processing

# Read non-empty, non-comment lines
with open("config.txt") as f:
    config_lines = [line.strip() for line in f 
                    if line.strip() and not line.startswith("#")]

When to Use Comprehensions

Good:

# Simple transformations
squares = [x**2 for x in numbers]
 
# Filtering
adults = [p for p in people if p.age >= 18]
 
# Creating dicts from pairs
mapping = {k: v for k, v in pairs}

Avoid:

# Too complex - use a loop instead
result = [
    transform(x) 
    for x in data 
    if condition1(x) 
    if condition2(x) 
    for y in x.items 
    if condition3(y)
]
 
# Side effects - use a loop
[print(x) for x in items]  # Bad
for x in items: print(x)   # Good

Performance Tips

# Generator for large data
sum(x**2 for x in range(1000000))  # Memory efficient
 
# List when you need to reuse
squares = [x**2 for x in range(100)]
print(max(squares))
print(min(squares))

Quick Reference

# List comprehension
[expr for x in iterable if cond]
 
# Dict comprehension
{key: val for x in iterable if cond}
 
# Set comprehension
{expr for x in iterable if cond}
 
# Generator expression
(expr for x in iterable if cond)
 
# Nested
[expr for x in outer for y in inner]
 
# Conditional expression
[a if cond else b for x in iterable]

Comprehensions make code more readable when used appropriately. Keep them simple—if it's hard to read, use a loop instead.

React to this post: