Python Comprehensions: Lists, Sets and Dictionaries
How list, set and dictionary comprehensions work, with filtering and transforming in one line. After this, you can replace simple build-a-list loops and read comprehensions in other people's code.
Course content
Sign in to save your progress.
-
Set Up Projects That Don't Break Each Other
-
Python Virtual Environments and pip: One Project, One Environment
-
Pinning Python Dependencies With requirements.txt
-
-
-
Organize Code Other People Can Read
-
Python Modules and Packages: Splitting One Big File
-
Python Imports: Why ModuleNotFoundError Keeps Happening
-
Python Classes: When a Dictionary Is No Longer Enough
-
-
-
Work With Real Files
-
Python File Handling: Open, Read, Write, and Always Use with
-
Python pathlib: Stop Building File Paths by Hand
-
Reading, Cleaning and Writing CSV Data in Python
-
-
-
Shorter Code That Still Says What It Does
-
Python Comprehensions: Lists, Sets and Dictionaries
-
When a Comprehension Should Be a Plain Loop
-
-
-
Prove It Works Before Someone Else Finds Out
-
Python Testing Basics With pytest
-
Debugging Python With print, logging and pdb
-
-
- Final Check: Python Intermediate
A comprehension builds a list, set or dictionary from another collection in one expression. It replaces the common pattern of "make an empty list, loop, append". Used for that pattern, it is shorter and easier to read. Used for everything, it isn't. This lesson is the first part. The next one is about where to stop.
Skip ahead: If you already write list, set and dictionary comprehensions with filters and know the difference between a filter if and an if/else value, continue to "When a Comprehension Should Be a Plain Loop."
The loop it replaces
prices = [1200, 450, 89, 2300, 150]
with_vat = []
for price in prices:
with_vat.append(round(price * 1.12, 2))
print(with_vat)
with_vat = [round(price * 1.12, 2) for price in prices]
print(with_vat)
[1344.0, 504.0, 99.68, 2576.0, 168.0]
[1344.0, 504.0, 99.68, 2576.0, 168.0]
Same result. Read the comprehension left to right: "the rounded price with VAT, for each price in prices". The 12% is an example rate for the exercise.
Filtering with if
Add if at the end to keep only some items:
prices = [1200, 450, 89, 2300, 150]
big = [p for p in prices if p >= 1000]
print(big)
[1200, 2300]
Choosing a value with if/else
This is the part that confuses people. An if at the end filters. An if/else at the front chooses the value, and keeps every item:
prices = [1200, 450, 89, 2300, 150]
labels = ["big" if p >= 1000 else "small" for p in prices]
print(labels)
['big', 'small', 'small', 'big', 'small']
Rule of thumb: if you want fewer items, the if goes at the end. If you want the same number of items with different values, if/else goes at the front. Writing [p for p in prices if p >= 1000 else 0] is a SyntaxError, because a filter has no else.
Set comprehensions: unique values
emails = ["Ana@Example.com", "ben@example.com", "ana@example.com ", "BEN@example.com"]
unique = {e.strip().lower() for e in emails}
print(sorted(unique))
['ana@example.com', 'ben@example.com']
Curly braces with a single value make a set, which drops duplicates. Four entries, two real people. Sets have no order, which is why the result is sorted before printing.
Dictionary comprehensions
Curly braces with key: value make a dictionary. Useful for building a lookup table:
products = [
{"sku": "KB-01", "name": "Keyboard", "price": 1200},
{"sku": "MS-02", "name": "Mouse", "price": 450},
{"sku": "CB-03", "name": "Cable", "price": 150},
]
by_sku = {p["sku"]: p for p in products}
print(by_sku["MS-02"]["name"])
price_list = {p["name"]: p["price"] for p in products if p["price"] >= 200}
print(price_list)
Mouse
{'Keyboard': 1200, 'Mouse': 450}
Finding a product by SKU in a list means checking every item. With the dictionary, it is one lookup, no matter how many products there are.
⚠ Warning: In a dictionary comprehension, duplicate keys don't cause an error. The last one silently wins. If two products share a SKU because of a data mistake, one of them disappears from by_sku. When the key should be unique, check it: len(by_sku) == len(products).
Swapping keys and values, zip and enumerate
codes = {"PH": "Philippines", "SG": "Singapore"}
print({name: code for code, name in codes.items()})
names = ["Ana", "Ben"]
scores = [88, 92]
print({n: s for n, s in zip(names, scores)})
print([f"{i}. {n}" for i, n in enumerate(names, start=1)])
{'Philippines': 'PH', 'Singapore': 'SG'}
{'Ana': 88, 'Ben': 92}
['1. Ana', '2. Ben']
What about generator expressions?
Round brackets look like a "tuple comprehension", but they make a generator: it produces values one at a time instead of building the whole list in memory. Handy inside functions like sum:
prices = [1200, 450, 89, 2300, 150]
print(sum(p for p in prices if p >= 1000))
3500
Generators are covered properly in Python Advanced. For now: if you only need to loop over the result once, like summing it, round brackets are enough.
Common mistakes
- Using a comprehension only for its side effect.
[print(p) for p in prices]builds a list ofNonevalues just to throw it away. Use a loop. - Mixing up filter and value. Covered above:
ifat the end,if/elseat the front. - Reusing a name.
[price for price in prices]is fine.[prices for prices in prices]runs, and nobody can read it.
💡 Tip: Search your code for = [] followed by a for loop with one append. Those are the safe places to start using comprehensions. If the loop has more than one statement inside, leave it alone for now.
What happens if you skip this step
Nothing breaks. Your loops work. But you will read other people's Python, and they use comprehensions everywhere: libraries, Stack Overflow answers, your coworkers' code. If you can't read them quickly, every one of them slows you down.
What does {n % 3 for n in range(10)} produce, and why is it only three values?
About
How list, set and dictionary comprehensions work, with filtering and transforming in one line. After this, you can replace simple build-a-list loops and read comprehensions in other people's code.
- Duration
- 5 min
- Last update
- 09/23/2026
Comments (0)
Sign in to commentNo comments yet.