Comprehensions
Learn how to write clean, concise list, dictionary, and set comprehensions in Python.
Comprehensions
A comprehension is a short, clean way to create a list, dictionary, or set from an existing sequence — all in one line. Instead of writing a loop that builds up a collection step by step, you express it in a single readable line.
Before comprehensions, you would write this:
numbers = [1, 2, 3, 4, 5]
squares = []
for number in numbers:
squares.append(number ** 2)
print(squares) # [1, 4, 9, 16, 25]With a list comprehension:
numbers = [1, 2, 3, 4, 5]
squares = [number ** 2 for number in numbers]
print(squares) # [1, 4, 9, 16, 25]Same result. One line. Much cleaner.
List comprehensions
The structure is:
[expression for item in iterable]expression— what you want to do with each itemitem— the variable name for each itemiterable— the sequence you are looping over
# double every number
numbers = [1, 2, 3, 4, 5]
doubled = [n * 2 for n in numbers]
print(doubled) # [2, 4, 6, 8, 10]
# convert to uppercase
names = ["ali", "sara", "omar"]
upper_names = [name.upper() for name in names]
print(upper_names) # ['ALI', 'SARA', 'OMAR']
# get the length of each word
words = ["Python", "is", "amazing"]
lengths = [len(word) for word in words]
print(lengths) # [6, 2, 7]Adding a condition — filtering
You can add an if at the end to only include items that pass a test:
[expression for item in iterable if condition]numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
# only even numbers
evens = [n for n in numbers if n % 2 == 0]
print(evens) # [2, 4, 6, 8, 10]
# only numbers greater than 5
big = [n for n in numbers if n > 5]
print(big) # [6, 7, 8, 9, 10]A real example — filter out empty strings from a list:
data = ["Ali", "", "Sara", " ", "Omar", ""]
clean = [name.strip() for name in data if name.strip()]
print(clean) # ['Ali', 'Sara', 'Omar'].strip() removes whitespace, and if name.strip() filters out anything that becomes empty after stripping.
if/else inside a comprehension
You can also transform items differently based on a condition. The if/else goes in the expression part — before the for:
[value_if_true if condition else value_if_false for item in iterable]numbers = [1, 2, 3, 4, 5, 6]
labels = ["even" if n % 2 == 0 else "odd" for n in numbers]
print(labels) # ['odd', 'even', 'odd', 'even', 'odd', 'even']Another example — pass or fail:
scores = [88, 45, 72, 38, 91, 55]
results = ["pass" if score >= 50 else "fail" for score in scores]
print(results) # ['pass', 'fail', 'pass', 'fail', 'pass', 'pass']Notice the two different positions of if:
- After the
for→ filters items in or out:[x for x in items if condition] - Before the
for→ transforms items:[a if condition else b for x in items]
They do different things. Both can be used together too.
Dictionary comprehensions
Same idea — but builds a dictionary instead of a list. Use {} and provide a key-value pair:
{key: value for item in iterable}# square each number and store as key: value
numbers = [1, 2, 3, 4, 5]
squares = {n: n ** 2 for n in numbers}
print(squares) # {1: 1, 2: 4, 3: 9, 4: 16, 5: 25}Build a dictionary from two lists:
names = ["Ali", "Sara", "Omar"]
scores = [88, 95, 72]
gradebook = {name: score for name, score in zip(names, scores)}
print(gradebook) # {'Ali': 88, 'Sara': 95, 'Omar': 72}With a condition — only include students who passed:
gradebook = {name: score for name, score in zip(names, scores) if score >= 75}
print(gradebook) # {'Ali': 88, 'Sara': 95}Flip keys and values:
original = {"name": "Ali", "age": 22, "city": "Lahore"}
flipped = {value: key for key, value in original.items()}
print(flipped) # {'Ali': 'name', 22: 'age', 'Lahore': 'city'}Set comprehensions
Same as list comprehensions — but uses {} and produces a set with no duplicates:
{expression for item in iterable}numbers = [1, 2, 2, 3, 3, 3, 4, 4, 4, 4]
unique_squares = {n ** 2 for n in numbers}
print(unique_squares) # {1, 4, 9, 16}Get unique first letters from a list of names:
names = ["Ali", "Sara", "Ahmed", "Sana", "Omar"]
first_letters = {name[0] for name in names}
print(first_letters) # {'A', 'S', 'O'}Nested comprehensions
You can nest a comprehension inside another. This is useful for flattening nested lists or building matrices.
Flatten a nested list:
matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
flat = [item for row in matrix for item in row]
print(flat) # [1, 2, 3, 4, 5, 6, 7, 8, 9]Read it left to right — for each row in matrix, for each item in that row, include item.
Build a multiplication table as a nested list:
table = [[row * col for col in range(1, 6)] for row in range(1, 6)]
for row in table:
print(row)Output:
[1, 2, 3, 4, 5]
[2, 4, 6, 8, 10]
[3, 6, 9, 12, 15]
[4, 8, 12, 16, 20]
[5, 10, 15, 20, 25]Do not over-nest. One level of nesting in a comprehension is fine. Two levels gets hard to read fast. If it takes more than a few seconds to understand, rewrite it as a normal loop — readability always wins.
Comprehension vs loop — when to use which
| Situation | Use |
|---|---|
| Simple transformation of a sequence | Comprehension |
| Filtering items from a sequence | Comprehension |
| Building a dict or set from a sequence | Comprehension |
| Complex logic with multiple steps | Loop |
| Side effects like printing or file writing | Loop |
| More than two conditions or levels of nesting | Loop |
A good rule — if the comprehension fits comfortably on one line and reads naturally, use it. If you are squinting to understand it, use a loop.
A real example
Process a list of raw order data — clean the names, calculate totals with tax, and only keep completed orders:
orders = [
{"customer": " ali ", "amount": 100, "status": "completed"},
{"customer": "sara", "amount": 250, "status": "pending"},
{"customer": " omar ", "amount": 75, "status": "completed"},
{"customer": "fatima", "amount": 180, "status": "cancelled"},
{"customer": "zainab", "amount": 320, "status": "completed"},
]
TAX_RATE = 0.15
completed = [
{
"customer": order["customer"].strip().title(),
"total": round(order["amount"] * (1 + TAX_RATE), 2)
}
for order in orders
if order["status"] == "completed"
]
for order in completed:
print(f"{order['customer']}: ${order['total']}")Output:
Ali: $115.0
Omar: $86.25
Zainab: $368.0Summary
| Type | Syntax | Returns |
|---|---|---|
| List comprehension | [expr for x in iter] | List |
| List with filter | [expr for x in iter if cond] | Filtered list |
| List with transform | [a if cond else b for x in iter] | Transformed list |
| Dict comprehension | {k: v for x in iter} | Dictionary |
| Set comprehension | {expr for x in iter} | Set |
| Nested | [x for row in matrix for x in row] | Flat list |