Dictionaries
๐ Dictionaries
๐ Creating and Accessing Dictionaries
person = {
"name": "Ada",
"age": 28,
"language": "Python"
}
print(person["name"]) # Ada
print(person.get("age")) # 28
print(person.get("email", "unknown")) # unknown โ default if key is missing
person["email"] # KeyError: 'email' โ crashes the program
person["email"] raises a KeyError immediately if the key doesn't exist โ there's no silent None the way some languages return. Use .get() whenever a key might legitimately be missing; it returns None (or your own default value) instead of crashing.
โ๏ธ Modifying Dictionaries
person["email"] = "ada@example.com" # adds a new key person["age"] = 29 # overwrites an existing key del person["language"] # removes a key entirely email = person.pop("email") # removes AND returns the value print("age" in person) # True โ membership testing checks KEYS
๐ Iterating Over Dictionaries
scores = {"Alice": 90, "Bob": 85, "Charlie": 78}
for name in scores.keys():
print(name) # Alice, Bob, Charlie
for score in scores.values():
print(score) # 90, 85, 78
for name, score in scores.items():
print(f"{name}: {score}") # Alice: 90, Bob: 85, Charlie: 78
Plain for name in scores: (no .keys()) also works and iterates over keys โ .keys() is optional but makes the intent explicit. .items() is the one to reach for whenever you need both the key and value together, pairing naturally with the tuple unpacking from the previous chapter.
Key-Value Collections: Go vs Kotlin vs Python
| Language | Type | Missing key behavior |
|---|---|---|
| Go | map[string]int | Returns the zero value silently (e.g. 0) โ no crash, no error, which can hide real bugs. The comma-ok idiom (v, ok := m[key]) is needed to actually detect a missing key. |
| Kotlin | Map<K, V> / MutableMap<K, V> | map[key] returns a nullable type (V?); map.getValue(key) throws if missing, directly comparable to Python's bracket-indexing/.get() split. |
| Python | dict | d[key] raises KeyError immediately; d.get(key, default) returns a default instead. |
โก Dict Comprehensions
The same comprehension pattern from the last chapter works for dictionaries too, using {key: value for ...}:
numbers = [1, 2, 3, 4] squares = {n: n ** 2 for n in numbers} print(squares) # {1: 1, 2: 4, 3: 9, 4: 16} # with a filtering condition: even_squares = {n: n ** 2 for n in numbers if n % 2 == 0} print(even_squares) # {2: 4, 4: 16}
Creating & Accessing
{key: value} literal, d[key] indexing, d.get(key, default) for safety.
Modifying
Assign to add/overwrite, del d[key] or d.pop(key) to remove.
Iterating
.keys(), .values(), .items() โ .items() for key+value pairs together.
Dict comprehension
{k: v for k, v in ... if condition} โ same pattern as list comprehensions.
๐ป Coding Challenges
Challenge 1: Word Frequency Counter
Given the list words = ["apple", "banana", "apple", "cherry", "banana", "apple"], build a dictionary counting how many times each word appears, using a loop and .get() with a default.
Goal: Practice the common "build a count dictionary from a list" pattern.
Challenge 2: Invert a Dictionary
Given capitals = {"France": "Paris", "Japan": "Tokyo", "Italy": "Rome"}, build a new dictionary with the keys and values swapped โ {"Paris": "France", "Tokyo": "Japan", "Rome": "Italy"} โ using a dict comprehension and .items().
Goal: Combine .items() iteration with a dict comprehension in one line.
Challenge 3: Safe Lookup Report
Given inventory = {"apples": 10, "bananas": 5} and a list of items to check, ["apples", "bananas", "cherries"], print a stock report line for each one โ using .get() so a missing item like "cherries" prints "0 in stock" instead of crashing.
Goal: Practice defensive dictionary lookups with .get() instead of direct indexing.
๐ฏ What's Next
Next chapter: Functions โ def, positional/keyword/default/*args/**kwargs parameters, return, and scope.