Python Reference

Python Comprehensions Cheat Sheet

A complete reference for Python list, dict, set comprehensions, generator expressions, conditionals, nested patterns, and performance.

4
Comprehension Types
40+
Examples
8
Categories
100%
Client-Side

📖List Comprehension

The most common and versatile comprehension — weave lists from iterables.

[x for x in iterable]
List

Basic list comprehension. Creates a new list by iterating over an iterable and collecting each element.

nums = [1, 2, 3, 4, 5]
result = [x for x in nums]
print(result)  # [1, 2, 3, 4, 5]
[x for x in iterable if condition]
List

Filter elements with a condition. Only items where the condition is True are included.

nums = [1, 2, 3, 4, 5, 6]
evens = [x for x in nums if x % 2 == 0]
print(evens)  # [2, 4, 6]
[x if condition else y for x in iterable]
List

Inline if-else to transform elements conditionally. The ternary expression goes before the for clause.

nums = [1, 2, 3, 4, 5]
labels = ["even" if x % 2 == 0 else "odd" for x in nums]
print(labels)  # ['odd', 'even', 'odd', 'even', 'odd']
[x*2 for x in iterable]
List

Transform each element during collection. Apply any expression or function call to the item.

nums = [1, 2, 3, 4]
doubled = [x * 2 for x in nums]
print(doubled)  # [2, 4, 6, 8]

words = ["a", "bb", "ccc"]
lengths = [len(w) for w in words]
print(lengths)  # [1, 2, 3]
[item for sublist in matrix for item in sublist]
List

Flatten a nested list (matrix) into a single list. Multiple for clauses read left to right like nested loops.

matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
flat = [item for sublist in matrix for item in sublist]
print(flat)  # [1, 2, 3, 4, 5, 6, 7, 8, 9]
[x+y for x in a for y in b]
List

Cartesian product — combine elements from multiple iterables. Equivalent to nested for loops.

a = [1, 2]
b = [10, 20]
sums = [x + y for x in a for y in b]
print(sums)  # [11, 21, 12, 22]
[f"{i}: {v}" for i, v in enumerate(items)]
List

Use enumerate inside a comprehension to get both index and value.

items = ["apple", "banana", "cherry"]
numbered = [f"{i}: {v}" for i, v in enumerate(items)]
print(numbered)
# ['0: apple', '1: banana', '2: cherry']
[f"{a}-{b}" for a, b in zip(list1, list2)]
List

Use zip to iterate over multiple lists in parallel inside a comprehension.

names = ["Alice", "Bob"]
scores = [95, 87]
pairs = [f"{n}: {s}" for n, s in zip(names, scores)]
print(pairs)  # ['Alice: 95', 'Bob: 87']
[x**2 for x in range(10)]
List

Combine range with comprehension to generate sequences of transformed numbers.

squares = [x**2 for x in range(10)]
print(squares)  # [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

odds = [x for x in range(20) if x % 2 == 1]
print(odds)  # [1, 3, 5, 7, 9, 11, 13, 15, 17, 19]
[s.upper() for s in words]
List

Apply string methods or any object method inside a comprehension.

words = ["hello", "world"]
upper = [s.upper() for s in words]
print(upper)  # ['HELLO', 'WORLD']

stripped = [s.strip() for s in ["  a  ", " b "]]
print(stripped)  # ['a', 'b']
[x for x in nums if x > 0 if x % 2 == 0]
List

Chain multiple if conditions. Both conditions must be True for the element to be included.

nums = [-4, -2, 0, 1, 2, 3, 4]
result = [x for x in nums if x > 0 if x % 2 == 0]
print(result)  # [2, 4]
List comp vs map/filter
ListPattern

List comprehensions are generally preferred over map/filter for readability and speed.

nums = [1, 2, 3, 4, 5]

# List comprehension (preferred)
evens_sq = [x**2 for x in nums if x % 2 == 0]

# Equivalent with map/filter
evens_sq2 = list(map(lambda x: x**2, filter(lambda x: x % 2 == 0, nums)))

📜Dict Comprehension

Weave dictionaries with key-value pairs from any iterable.

{k: v for k, v in zip(keys, values)}
Dict

Basic dict comprehension from two parallel iterables using zip.

keys = ["a", "b", "c"]
values = [1, 2, 3]
d = {k: v for k, v in zip(keys, values)}
print(d)  # {'a': 1, 'b': 2, 'c': 3}
{x: x**2 for x in range(5)}
Dict

Create a dict from a single iterable, using the element as both key and transformed value.

squares = {x: x**2 for x in range(5)}
print(squares)  # {0: 0, 1: 1, 2: 4, 3: 9, 4: 16}

chars = {c: ord(c) for c in "abc"}
print(chars)  # {'a': 97, 'b': 98, 'c': 99}
{k: v for k, v in d.items() if v > 0}
Dict

Filter a dictionary by its values (or keys) using a condition.

data = {"a": 1, "b": -2, "c": 3, "d": -4}
positive = {k: v for k, v in data.items() if v > 0}
print(positive)  # {'a': 1, 'c': 3}
{v: k for k, v in d.items()}
Dict

Invert a dictionary — swap keys and values. Values must be unique and hashable.

original = {"a": 1, "b": 2, "c": 3}
inverted = {v: k for k, v in original.items()}
print(inverted)  # {1: 'a', 2: 'b', 3: 'c'}
{k: (v if v > 0 else 0) for k, v in d.items()}
Dict

Use inline if-else to conditionally transform values while keeping all keys.

data = {"a": 1, "b": -2, "c": 3}
clamped = {k: (v if v > 0 else 0) for k, v in data.items()}
print(clamped)  # {'a': 1, 'b': 0, 'c': 3}
Grouping with setdefault pattern
DictPattern

Dict comprehension alternative for grouping. Note: comprehensions cannot easily group, use a loop for that.

items = [("fruit", "apple"), ("veg", "carrot"), ("fruit", "banana")]

# Use a loop for grouping
groups = {}
for k, v in items:
    groups.setdefault(k, []).append(v)
print(groups)
# {'fruit': ['apple', 'banana'], 'veg': ['carrot']}
{k: v for d in dicts for k, v in d.items()}
DictPattern

Merge multiple dictionaries with a comprehension. Later dicts overwrite earlier ones for duplicate keys.

dicts = [{"a": 1}, {"b": 2}, {"a": 3}]
merged = {k: v for d in dicts for k, v in d.items()}
print(merged)  # {'a': 3, 'b': 2}
{i: {j: i*j for j in range(3)} for i in range(3)}
DictNested

Nested dict comprehension to create a 2D lookup table or matrix of dictionaries.

table = {i: {j: i*j for j in range(3)} for i in range(3)}
print(table)
# {0: {0: 0, 1: 0, 2: 0}, 1: {0: 0, 1: 1, 2: 2}, 2: {0: 0, 1: 2, 2: 4}}

🔷Set Comprehension

Weave unique collections with automatic deduplication.

{x for x in iterable}
Set

Basic set comprehension. Creates a set, automatically removing duplicates.

nums = [1, 2, 2, 3, 3, 3]
unique = {x for x in nums}
print(unique)  # {1, 2, 3}
{x for x in iterable if x > 0}
Set

Filter elements while building a set. Only unique values passing the condition are kept.

nums = [-2, -1, 0, 1, 2, 3]
positive = {x for x in nums if x > 0}
print(positive)  # {1, 2, 3}
{x.lower() for x in words}
Set

Deduplicate strings case-insensitively by normalizing before adding to the set.

words = ["Apple", "apple", "APPLE", "Banana"]
normalized = {x.lower() for x in words}
print(normalized)  # {'apple', 'banana'}
Set comprehension vs set()
SetPattern

Set comprehensions are often clearer than passing a generator to set(), especially with conditions.

nums = [1, 2, 3, 4, 5]

# Set comprehension (preferred)
evens = {x for x in nums if x % 2 == 0}

# Equivalent with set()
evens2 = set(x for x in nums if x % 2 == 0)
Mathematical operations via comprehension
Set

Use set comprehensions for mathematical set construction like squares, primes, or multiples.

squares = {x**2 for x in range(10)}
print(squares)  # {0, 1, 4, 9, 16, 25, 36, 49, 64, 81}

multiples_of_3 = {x for x in range(30) if x % 3 == 0}
print(multiples_of_3)  # {0, 3, 6, 9, 12, 15, 18, 21, 24, 27}
Nested set comprehension
SetNested

Flatten and deduplicate in one pass using nested set comprehensions.

matrix = [[1, 2, 2], [3, 3, 4], [1, 4, 5]]
unique_flat = {x for row in matrix for x in row}
print(unique_flat)  # {1, 2, 3, 4, 5}

Generator Expression

Lazy evaluation for memory-efficient iteration over large datasets.

(x for x in iterable)
Generator

Basic generator expression. Returns a generator object, not a list. Values are computed on demand.

gen = (x for x in range(5))
print(gen)  # <generator object>

print(next(gen))  # 0
print(next(gen))  # 1
print(list(gen))  # [2, 3, 4]
sum(x**2 for x in range(1000000))
Generator

Memory efficiency: generator expressions compute one value at a time, never storing the full sequence.

# Generator — memory efficient
total = sum(x**2 for x in range(1000000))

# List comprehension — stores all values
total2 = sum([x**2 for x in range(1000000)])
(x for x in iterable if x > 0)
Generator

Filter with a generator expression. The condition is evaluated lazily as values are requested.

nums = [-3, -1, 0, 2, 4]
positive = (x for x in nums if x > 0)
print(list(positive))  # [2, 4]
Chaining generators
Generator

Chain generator expressions to build data pipelines without intermediate lists.

nums = [-5, -2, 0, 3, 4, 7]
pipeline = (x*2 for x in (x for x in nums if x > 0))
print(list(pipeline))  # [6, 8, 14]
Generator vs list comp performance
GeneratorPerformance

Generators shine for large data and single-pass operations. Lists are better for repeated access or indexing.

import sys

gen = (x for x in range(1000000))
lst = [x for x in range(1000000)]

print(sys.getsizeof(gen))  # ~112 bytes
print(sys.getsizeof(lst))  # ~8,000,000 bytes
next((x for x in items if x > 0), None)
Generator

Find the first matching element with a default value. Stops at the first match — very efficient.

items = [-5, -2, 0, 3, 4]
first_positive = next((x for x in items if x > 0), None)
print(first_positive)  # 3

# With default when not found
first_big = next((x for x in items if x > 100), "not found")
print(first_big)  # not found

Conditionals & Logic

Filtering and branching inside comprehensions.

Single if filter
Conditional

Place a single if after the for clause to filter elements. The condition must evaluate to True for inclusion.

nums = [1, 2, 3, 4, 5, 6]
evens = [x for x in nums if x % 2 == 0]
print(evens)  # [2, 4, 6]
if-else inline
Conditional

Use a ternary expression before the for clause to conditionally transform each element.

nums = [1, 2, 3, 4]
result = ["even" if x % 2 == 0 else "odd" for x in nums]
print(result)  # ['odd', 'even', 'odd', 'even']
Multiple if filters chained
Conditional

Chain multiple if conditions. All conditions must be True (AND logic).

nums = range(20)
result = [x for x in nums
          if x % 2 == 0
          if x % 3 == 0
          if x > 0]
print(result)  # [6, 12, 18]
Walrus operator in comprehension
ConditionalPattern

Use the walrus operator (:=) to assign and test in one expression. Python 3.8+.

import re
lines = ["abc 123", "no digits", "456 xyz"]
matches = [m.group(0) for line in lines
           if (m := re.search(r'\d+', line))]
print(matches)  # ['123', '456']

📏Nested Comprehensions

Multi-dimensional weaving with nested loops inside comprehensions.

Matrix transpose
Nested

Transpose a matrix using nested list comprehension. Swap rows and columns.

matrix = [[1, 2, 3],
         [4, 5, 6],
         [7, 8, 9]]

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

Create nested dictionaries with comprehensions. Useful for lookup tables and grouping.

table = {
    i: {f"col_{j}": i * j for j in range(3)}
    for i in range(3)
}
print(table)
# {0: {'col_0': 0, 'col_1': 0, 'col_2': 0}, ...}
Nested vs flat with multiple for
Nested

Understand the difference between nested comprehensions and multiple for clauses in one comprehension.

# Nested — produces a list of lists
nested = [[i * j for j in range(3)] for i in range(3)]
print(nested)  # [[0, 0, 0], [0, 1, 2], [0, 2, 4]]

# Flat — produces a single list
flat = [i * j for i in range(3) for j in range(3)]
print(flat)  # [0, 0, 0, 0, 1, 2, 0, 2, 4]

Performance & Patterns

Speed, memory, and when to use (or avoid) comprehensions.

List comp vs for loop speed
Performance

List comprehensions are typically faster than equivalent for loops because the iteration runs in C.

# List comprehension — faster
squares = [x**2 for x in range(1000)]

# For loop — slower but equivalent
squares2 = []
for x in range(1000):
    squares2.append(x**2)

# ~1.5-2x speedup with comprehension
List comp vs map() performance
Performance

List comprehensions are often faster than map() with lambda, and always more readable.

nums = range(1000)

# List comprehension — preferred
result = [x**2 for x in nums]

# map with lambda — less readable
result2 = list(map(lambda x: x**2, nums))

# map with existing function — acceptable
result3 = list(map(str, nums))
Generator expression memory benefit
Performance

For large datasets, generator expressions use constant memory regardless of input size.

import sys

# Generator — constant memory
gen = (x**2 for x in range(10_000_000))
print(sys.getsizeof(gen))  # ~112 bytes

# List — proportional memory
lst = [x**2 for x in range(10_000_000)]
print(sys.getsizeof(lst))  # ~80 MB
When NOT to use comprehension
Performance

Avoid comprehensions for side effects, complex logic, or when readability suffers. Use a plain loop instead.

# BAD: side effect in comprehension
[print(x) for x in items]  # Creates a list of Nones

# GOOD: use a plain loop
for x in items:
    print(x)

# BAD: too complex
result = [f(x) if cond1(x) else g(x) if cond2(x) else x for x in items]

# GOOD: use a function
result = [categorize(x) for x in items]
Dict comprehension for frequency counting
PerformancePattern

While Counter is best, you can build frequency dicts with comprehensions for simple cases.

from collections import Counter

words = ["apple", "banana", "apple", "cherry", "banana", "apple"]

# Best: use Counter
freq = Counter(words)

# Alternative: dict comprehension with count()
freq2 = {w: words.count(w) for w in set(words)}
print(freq2)  # {'apple': 3, 'banana': 2, 'cherry': 1}
Set comprehension for uniqueness check
PerformancePattern

Use set comprehensions for O(1) membership tests and deduplication.

items = ["a", "b", "a", "c", "b"]
unique = {x for x in items}

# Fast membership test
print("a" in unique)  # True — O(1)

# Check if all unique
print(len(items) == len(unique))  # False

📊List Comp vs For Loop vs map/filter

When to choose which approach for transforming iterables.

ApproachSyntaxSpeedReadabilityUse Case
List comprehension[f(x) for x in items]FastestExcellentMost transformations and filters
For loopfor x in items: result.append(f(x))SlowerGoodSide effects, complex logic
map()map(f, items)FastPoor (with lambda)Existing function, no filter
filter()filter(cond, items)FastPoor (with lambda)Existing predicate function
map + filtermap(f, filter(cond, items))FastVery poorRarely — use list comp instead

📊Comprehension Type Comparison

Quick reference for choosing the right comprehension type.

TypeSyntaxMemoryEvaluationUse Case
List[x for x in items]O(n)EagerNeed all results, indexing, repeated access
Dict{k: v for k, v in items}O(n)EagerKey-value mappings, lookups
Set{x for x in items}O(n)EagerUniqueness, membership tests
Generator(x for x in items)O(1)LazyLarge data, single-pass, chaining

🌟Pro Tips

Wisdom from the loom — best practices and gotchas.

01
Don't use comprehensions for side effects
Comprehensions build collections. If you only need side effects (printing, appending to external state), use a plain for loop. [print(x) for x in items] creates a list of Nones — wasteful and confusing.
02
Keep it readable
If a comprehension spans more than 2 lines or has nested if-else chains, extract it into a function. Readability beats brevity. The next developer to read your code will thank you.
03
Nested comprehensions can be hard to read
Nested list comprehensions (comprehension inside comprehension) are often less readable than flat multiple-for comprehensions. Prefer [x for row in matrix for x in row] over nested brackets when flattening.
04
Generator expressions for large data
When processing files, streams, or large datasets, always prefer generator expressions. They use constant memory and can be chained into elegant data pipelines without loading everything into RAM.
05
Walrus operator (Python 3.8+)
The walrus operator := lets you assign and test in one expression inside comprehensions. Great for regex matching and expensive computations: [m.group() for line in lines if (m := re.search(..., line))].
06
Avoid complex if-else chains
If your comprehension needs multiple elif-style branches, it's too complex. Use a helper function: [categorize(x) for x in items] is cleaner than a 3-level ternary inside brackets.