Dictionaries
1.4 Dictionaries
Fast lookup, iteration, and comprehension patterns
Dictionaries are one of the most important data structures in Python and one of the most frequently tested in interviews.
A dictionary stores key → value mappings.
You will use them constantly in:
- API payloads
- JSON data
- frequency counting
- grouping
- caching
- lookup tables
- object mappings by ID
A large number of interview problems become dramatically simpler once you recognize that a dictionary is the right tool.
Examples:
- count word frequencies
- group users by city
- memoization / caching
- map IDs to objects
- deduplicate while preserving metadata
This chapter focuses on how to think about dictionaries as hash maps, not just memorize methods.
1.4.1 Mental model: what a dictionary really is
A dictionary is a mapping from keys to values.
Example
user = {
"name": "Ruben",
"age": 30
}
Here:
"name"is the key"Ruben"is the value
Why dictionaries are powerful
The main reason dictionaries are so important is fast lookup.
user["name"]
Result
"Ruben"
Average lookup complexity:
O(1)
This is one of the most common interview questions.
1.4.2 How lookup works conceptually
Python dictionaries use hashing.
Mental model
key -> hash -> bucket -> value
Example
prices = {
"apple": 2,
"banana": 1
}
When you do:
prices["apple"]
Python:
- hashes
"apple" - finds the bucket
- retrieves the value
This is why lookup is usually constant time.
A strong verbal answer should mention hash table / hash map.
1.4.3 Accessing values safely with get()
This is one of the most important dictionary methods.
Basic access
user["name"]
Works if the key exists.
The problem
user["email"]
Raises:
KeyError
This is a very common bug source.
Safe access with get()
user.get("email")
Result
None
No error.
This is why get() is extremely important.
Default value
user.get("email", "not provided")
Result
"not provided"
This is heavily used in backend code.
Common interview pattern: frequency counting
This is one of the most important use cases.
words = ["a", "b", "a"]
counts = {}
for word in words:
counts[word] = counts.get(word, 0) + 1
Result
{"a": 2, "b": 1}
This pattern comes up constantly.
1.4.4 items()
This is one of the most important iteration tools.
Basic usage
user = {
"name": "Ruben",
"age": 30
}
for key, value in user.items():
print(key, value)
Output
name Ruben
age 30
This is the most Pythonic way to iterate over both key and value.
Compare iteration methods
Keys only
for key in user:
...
for key in user.keys():
...
Values only
for value in user.values():
...
Key + value
for key, value in user.items():
...
This is the most common interview pattern.
1.4.5 Dictionary comprehensions
One of the most important Pythonic features.
Basic syntax
squares = {x: x * x for x in range(5)}
Result
{0: 0, 1: 1, 2: 4, 3: 9, 4: 16}
This is the dictionary equivalent of list comprehensions.
Mental model
Equivalent to:
squares = {}
for x in range(5):
squares[x] = x * x
A strong interview answer should understand both forms.
Conditional dictionary comprehension
evens = {x: x * x for x in range(10) if x % 2 == 0}
Result
{0: 0, 2: 4, 4: 16, 6: 36, 8: 64}
This is a common live-coding pattern.
1.4.6 Important dictionary methods
These should definitely be included.
keys()
user.keys()
Returns the keys.
values()
user.values()
Returns the values.
update()
user.update({"city": "Brussels"})
Used to merge new fields.
Membership
"name" in user
Checks whether a key exists.
Average complexity:
O(1)
Very important interview point.
1.4.7 Important dictionary interview patterns
Frequency counting
counts[word] = counts.get(word, 0) + 1
Extremely common.
Grouping
people = [
{"name": "A", "city": "Ghent"},
{"name": "B", "city": "Brussels"},
{"name": "C", "city": "Ghent"}
]
grouped = {}
for person in people:
city = person["city"]
grouped.setdefault(city, []).append(person)
This is a very realistic backend pattern.
Lookup by ID
users_by_id = {
1: {"name": "A"},
2: {"name": "B"}
}
Very common in services and APIs.
1.4.8 Common interview problems
Dictionaries are used in:
- two sum
- frequency counting
- grouping
- caching
- LRU logic
- graph adjacency maps
- memoization
This chapter is foundational.
Verbal interview questions
Answer these out loud:
- Why is dictionary lookup usually
O(1)? - Why use
get()instead of direct indexing? - Explain
items() - Explain dictionary comprehension
- When would you use a dictionary over a list?
Coding drills
Drill 1: word frequency
def count_words(words: list[str]) -> dict[str, int]:
...
Drill 2: group by city
def group_by_city(people: list[dict]) -> dict[str, list]:
...
Drill 3: invert mapping
def invert(d: dict[str, int]) -> dict[int, str]:
...
Example
{"a": 1, "b": 2} -> {1: "a", 2: "b"}