datarekha
Python Easy Asked at AmazonAsked at GoogleAsked at Meta

How do you use dict comprehensions effectively, and what are common patterns in data work?

The short answer

A dict comprehension uses the syntax `{key_expr: value_expr for item in iterable if condition}` to build a dictionary in one expression. It is faster than calling `dict()` on a list of pairs and more readable than a for-loop with repeated `d[k] = v` assignments. Common data patterns include inverting a dict, grouping values, and transforming keys or values in bulk.

How to think about it

A dict comprehension is the list comprehension’s idea carried over to key-value pairs. The shape is {key: value for item in iterable if condition} — the same filtering and transforming power, but you get a dict back. In data work it turns up everywhere: building lookup tables, normalising messy keys, inverting mappings. What an interviewer is checking is that you read and write it fluently, recognise the everyday patterns, and know the one silent gotcha — duplicate values when you invert.

The simplest form turns a range into a dict:

squares = {x: x**2 for x in range(10) if x % 2 == 0}
# {0: 0, 2: 4, 4: 16, 6: 36, 8: 64}

A worked example

Five patterns you’ll reach for again and again — invert, normalise keys, build a lookup, filter by value, and the grouping case a dict comprehension can’t do on its own:

# Invert a mapping (swap keys and values)
original = {"a": 1, "b": 2, "c": 3}
inverted = {v: k for k, v in original.items()}
print("Inverted:", inverted)

# Normalise messy keys (strip + lowercase)
raw = {"  Name ": "Alice", "AGE": 30, " CITY ": "NYC"}
clean = {k.strip().lower(): v for k, v in raw.items()}
print("Cleaned:", clean)

# Build a lookup table from a list of records
users = [
    {"id": 1, "name": "Alice", "score": 88},
    {"id": 2, "name": "Bob",   "score": 45},
    {"id": 3, "name": "Carol", "score": 91},
]
by_id = {u["id"]: u["name"] for u in users}
print("By ID:", by_id)

# Filter by value
scores  = {u["name"]: u["score"] for u in users}
passing = {name: s for name, s in scores.items() if s >= 50}
print("Passing:", passing)

# Grouping needs a defaultdict — one key maps to MANY values
from collections import defaultdict
dept_members = [("eng", "Alice"), ("eng", "Bob"), ("sales", "Carol")]
by_dept = defaultdict(list)
for dept, name in dept_members:
    by_dept[dept].append(name)
print("By dept:", dict(by_dept))

# The gotcha: inverting when values aren't unique — last key wins
dupes = {"a": 1, "b": 1, "c": 2}
risky = {v: k for k, v in dupes.items()}
print("Risky invert (last key wins):", risky)   # 'a' is gone
Inverted: {1: 'a', 2: 'b', 3: 'c'}
Cleaned: {'name': 'Alice', 'age': 30, 'city': 'NYC'}
By ID: {1: 'Alice', 2: 'Bob', 3: 'Carol'}
Passing: {'Alice': 88, 'Carol': 91}
By dept: {'eng': ['Alice', 'Bob'], 'sales': ['Carol']}
Risky invert (last key wins): {1: 'b', 2: 'c'}

Look at the last line. Both a and b mapped to 1, so inverting collapses them — b was written last, and a simply vanished. No error, no warning, just quiet data loss. That’s the one to remember.

Why it beats dict() on a list of pairs

A dict comprehension builds the mapping directly; dict([(k, v) for ...]) first materialises a throwaway list of tuples and then walks it. Over millions of records the comprehension is both faster and lighter on memory.

Learn it properly Comprehensions

Keep practising

All Python questions

Explore further

Skip to content