Skip to Content
Python Intermediate: Write Code You Won't Be Embarrassed to Share
Intermediate
0 likes
Courses
Python Intermediate: Write Code You Won't Be Embarrassed to Share

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.

Course Home

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 of None values just to throw it away. Use a loop.
  • Mixing up filter and value. Covered above: if at the end, if/else at 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
Was this helpful?
​ 0 ​ 0

Comments (0)

Sign in to comment

No comments yet.