PythonDict & Set Comprehensions

Dict & Set Comprehensions

Python extends the list comprehension idea to two other built-in collections: dictionaries and sets. The syntax is almost identical to a list comprehension — only the brackets and the shape of the expression change. If you are comfortable with [expr for item in iterable], dict and set comprehensions will feel immediately familiar.

Dict Comprehensions

A dict comprehension uses curly braces and a key-value pair as the expression: {k: v for k, v in iterable}. It builds a new dictionary by evaluating the key and the value for every item.

Python
names = ["ada", "grace", "linus"]

# {k: v for k, v in ...} - here we pair each name with its length
name_lengths = {name: len(name) for name in names}
print(name_lengths)  # {'ada': 3, 'grace': 5, 'linus': 5}

# Building from an existing dict
prices = {"apple": 1.50, "bread": 3.00, "milk": 2.20}
with_tax = {item: round(price * 1.08, 2) for item, price in prices.items()}
print(with_tax)  # {'apple': 1.62, 'bread': 3.24, 'milk': 2.38}
Set Comprehensions

A set comprehension looks like a dict comprehension but with a single expression instead of a key-value pair: {expr for item in iterable}. It builds a new set, so duplicate results are automatically collapsed into one.

Python
words = ["Apple", "banana", "apple", "Banana", "cherry"]

unique_lower = {w.lower() for w in words}
print(unique_lower)  # {'apple', 'banana', 'cherry'}
print(len(unique_lower))  # 3 - duplicates collapsed regardless of case
Note
The only visual difference between an empty dict comprehension's result and a set is the braces you write in the *source* — `{}` on its own always means an empty dict, never an empty set. To make an empty set you must call `set()`. This only matters for empty literals; `{expr for ...}` and `{k: v for ...}` are unambiguous because Python can see whether you wrote a colon.
Practical Example: Inverting a Dictionary

A very common use of dict comprehensions is swapping keys and values, which is useful when you need to look values up by what used to be the value.

Python
status_codes = {200: "OK", 404: "Not Found", 500: "Server Error"}

code_by_message = {message: code for code, message in status_codes.items()}
print(code_by_message)
# {'OK': 200, 'Not Found': 404, 'Server Error': 500}
Tip
Inverting only works cleanly when the original values are unique and hashable. If two keys share the same value, the inversion will silently drop one of them because a dict cannot have duplicate keys — the last pair processed wins.
Practical Example: Deduplicating While Transforming

Set comprehensions are the natural tool when you want to both transform every element and remove duplicates in one pass, rather than transforming a list and then wrapping it in set() afterward.

Python
emails = [
    "Ada@Example.com",
    "grace@example.com",
    "ADA@example.com",
    "linus@example.com",
]

unique_domains = {email.split("@")[1].lower() for email in emails}
print(unique_domains)  # {'example.com'}

normalized_emails = {email.lower() for email in emails}
print(normalized_emails)
# {'ada@example.com', 'grace@example.com', 'linus@example.com'}
Combining Comprehensions with Conditions

Just like list comprehensions, both dict and set comprehensions accept a trailing if clause to filter which source items are included.

Python
scores = {"alice": 92, "bob": 58, "carol": 74, "dave": 40}

# Dict comprehension with a filter - keep only passing scores
passing = {name: score for name, score in scores.items() if score >= 60}
print(passing)  # {'alice': 92, 'carol': 74}

# Set comprehension with a filter - names of everyone who failed
failed_names = {name for name, score in scores.items() if score < 60}
print(failed_names)  # {'bob', 'dave'}
  • Dict comprehension: {k: v for k, v in items if cond} builds a dictionary, keeping only pairs where cond is true.

  • Set comprehension: {expr for item in iterable if cond} builds a set, keeping only items where cond is true and collapsing duplicates.

  • Both are generally faster and more readable than building the same structure with an explicit loop and repeated assignment or .add() calls.