Skip to content

Comprehensions

Comprehensions are a short and quick way to build new collections from data you already have. They let you write a loop, an optional filter, and a transformation, all in just one line, as long as the logic stays simple.

Without a comprehension, you’d normally write a loop, maybe a condition, and then add each item one by one.

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

The same thing written in just one line:

result = [x**2 for x in range(10) if x % 2 == 0]
  • A comprehension puts a loop, a filter, and a result expression all together in one line
  • It cuts down on the extra setup code you’d normally write
  • It works best when the transformation is simple and easy to understand at first glance
[expression for item in iterable if condition]
PartWhat It Means
expressionWhat you want to create
itemThe current item being looked at
iterableThe collection you’re going through
conditionAn optional filter
graph TD Start --> Loop["Take the next item"] Loop --> Condition{"Does it match the filter?"} Condition -->|Yes| Transform["Run the expression"] Transform --> Store["Add result to collection"] Store --> Loop Condition -->|No| Loop Loop --> End["Collection is complete"]

A list comprehension builds a brand new list from an existing collection.

squares = [x**2 for x in range(10)]
even_squares = [x**2 for x in range(10) if x % 2 == 0]
even_squares = []
for x in range(10):
if x % 2 == 0:
even_squares.append(x**2)
pairs = [(x, y) for x in range(2) for y in range(2)]
# Output: [(0, 0), (0, 1), (1, 0), (1, 1)]
labels = ["even" if x % 2 == 0 else "odd" for x in range(5)]

A set comprehension builds a set, which means any duplicate values automatically get removed.

unique_squares = {x**2 for x in range(10)}
  • When you want to remove duplicate values
  • When you want to quickly build a set for easy lookup
nums = [1, 2, 2, 3]
unique = {x for x in nums} # {1, 2, 3}

A dictionary comprehension creates key-value pairs from a collection.

square_dict = {x: x**2 for x in range(5)}
filtered = {x: x**2 for x in range(10) if x % 2 == 0}
words = ["apple", "banana", "cherry"]
length_map = {word: len(word) for word in words}

Generator expressions look like list comprehensions, but they use round brackets () instead of square brackets []. Instead of building the whole result all at once, they give you one value at a time, only when you ask for it.

gen = (x**2 for x in range(10))
  • A list comprehension builds the entire list right away
  • A generator expression only creates each item when it’s actually needed
for value in gen:
print(value)
graph TD List["List comprehension"] --> A["Stores every value at once"] Gen["Generator expression"] --> B["Produces one value at a time"]

1. Less work happening behind the scenes in Python

Section titled “1. Less work happening behind the scenes in Python”
  • A regular loop usually involves several repeated steps that Python has to handle each time
  • A comprehension keeps things tighter and simpler for Python to process
# loop style
result.append(x)
# comprehension style
[x for x in iterable]

The variable you use inside a comprehension stays only inside that comprehension - it doesn’t spill out into the rest of your code.

# Loop
result = []
for x in range(1000000):
result.append(x)
# Comprehension
result = [x for x in range(1000000)]

For simple tasks like this, the comprehension version is usually shorter to write and often runs faster too.

  • When the logic is short and straightforward
  • When you’re just transforming or filtering one collection into another
  • When the result naturally fits into a single line
  • When the logic has too many branches or conditions
  • When you need several nested if-conditions
  • When a regular loop would honestly be easier to read and fix if something goes wrong

This is way too packed and confusing for a comprehension:

result = [x*y for x in range(10) for y in range(10) if x % 2 == 0 if y % 3 == 0]

The loop version is much easier to read and follow:

result = []
for x in range(10):
if x % 2 != 0:
continue
for y in range(10):
if y % 3 == 0:
result.append(x*y)
x = 10
lst = [x for x in range(5)]
print(x) # 10

Comprehensions Inside Comprehensions (Nested)

Section titled “Comprehensions Inside Comprehensions (Nested)”
matrix = [[i*j for j in range(3)] for i in range(3)]
[
[0, 0, 0],
[0, 1, 2],
[0, 2, 4],
]
users = [{"active": True}, {"active": False}]
active_users = [u for u in users if u["active"]]
prices = [100, 200, 300]
discounted = [p * 0.9 for p in prices]

Turning a List of Lists Into One Flat List

Section titled “Turning a List of Lists Into One Flat List”
matrix = [[1, 2], [3, 4]]
flat = [num for row in matrix for num in row]