S3.0 What This Teaches
dict type:- Creating and initializing dictionaries
- Accessing, adding, updating, and deleting entries
- Safe access with
get()andsetdefault() - Iterating keys, values, and items
- Merging and unpacking dicts
- Useful relatives:
collections.defaultdictandCounter
S3.1 Creating and Initializing
# Literal syntax - keys must be hashable
capitals = {"France": "Paris", "Germany": "Berlin", "Japan": "Tokyo"}
# dict() constructor
ages = dict(Alice=30, Bob=25, Carol=35)
# From list of pairs
pairs = [("one", 1), ("two", 2), ("three", 3)]
d = dict(pairs)
# Dict comprehension
squares = {n: n**2 for n in range(1, 6)}
print(squares) # {1: 1, 2: 4, 3: 9, 4: 16, 5: 25}
S3.2 Accessing and Updating
d = {"a": 1, "b": 2, "c": 3}
print(d["a"]) # 1
d["a"] = 10 # update existing
d["d"] = 4 # add new key
del d["b"] # remove key (KeyError if missing)
removed = d.pop("c") # remove and return (KeyError if missing)
removed = d.pop("x", None) # safe - returns None if missing
d.clear() # remove all
print(len(d)) # 0
S3.3 Safe Access
d = {"a": 1, "b": 2}
# get() - returns None (or a default) instead of raising KeyError
print(d.get("a")) # 1
print(d.get("x")) # None
print(d.get("x", -1)) # -1
# setdefault() - inserts and returns default if key missing
d.setdefault("c", 0) # d["c"] = 0 (only if "c" not in d)
d["c"] += 1 # now safe to increment
# in operator
print("a" in d) # True
print("z" in d) # False
S3.4 Iterating
capitals = {"France": "Paris", "Germany": "Berlin", "Japan": "Tokyo"}
# Iterate keys (default)
for country in capitals:
print(country)
# Iterate values
for capital in capitals.values():
print(capital)
# Iterate key-value pairs
for country, capital in capitals.items():
print(f"{country}: {capital}")
# Python 3.7+ guarantees insertion-order
print(list(capitals.keys())) # ['France', 'Germany', 'Japan']
S3.5 Merging and Unpacking
defaults = {"theme": "light", "font": "mono", "size": 12}
user = {"theme": "dark", "size": 14}
# | operator (Python 3.9+) - right side wins on conflicts
merged = defaults | user
print(merged) # {'theme': 'dark', 'font': 'mono', 'size': 14}
# |= update in place
defaults |= user
# Unpack with ** (older style)
merged2 = {**defaults, **user}
S3.6 defaultdict and Counter
from collections import defaultdict, Counter
# defaultdict - missing keys get a default value automatically
groups = defaultdict(list)
for word in ["apple", "ant", "bat", "bear", "cat"]:
groups[word[0]].append(word)
print(dict(groups))
# {'a': ['apple', 'ant'], 'b': ['bat', 'bear'], 'c': ['cat']}
# Counter - counts hashable items
text = "the quick brown fox jumps over the lazy dog the fox"
freq = Counter(text.split())
print(freq.most_common(3)) # [('the', 3), ('fox', 2), ...]
print(freq["the"]) # 3
print(freq["missing"]) # 0 (no KeyError!)
S3.7 Example - All Together
# Dicts - word frequency counter and grouping by length.
from collections import Counter, defaultdict
text = "the quick brown fox jumps over the lazy dog the fox"
freq = Counter(text.split())
print("Top 3 words:")
for word, count in freq.most_common(3):
print(f" {word:<10} {count}")
# Group by word length
by_length = defaultdict(list)
for word in set(text.split()):
by_length[len(word)].append(word)
print("\nBy length:")
for length in sorted(by_length):
print(f" {length}: {sorted(by_length[length])}")
S3.8 Exercise
Exercise
- Build a phone book dict mapping names to phone numbers. Use
get()to look up several names safely, printing "not found" for missing ones. - Use
Counterto count letter frequencies in a sentence (ignoring spaces and punctuation). Print the 5 most common letters. - Use
defaultdict(list)to group a list of (category, item) tuples into a dict mapping each category to its list of items.
S3.9 Common Mistakes
Using d[key] when the key might not exist
count = d["missing_key"] # KeyError
count = d.get("missing_key", 0) # safe default
Using a mutable type as a dict key
d = {[1, 2]: "value"} # TypeError: unhashable type: 'list'
d = {(1, 2): "value"} # OK - tuples are hashable
Modifying a dict while iterating over it
for key in d:
if some_condition(key):
del d[key] # RuntimeError: dictionary changed size during iteration
# Fix: iterate a copy of the keys
for key in list(d.keys()):
if some_condition(key): del d[key]
S3.10 Key Terms
| Term | Meaning |
|---|---|
| dict | Mutable mapping of unique hashable keys to values; insertion-ordered since 3.7 |
| get() | Returns value or a default; no KeyError on missing key |
| setdefault() | Inserts and returns a default value if key is missing |
| items() | View of (key, value) pairs; supports iteration and membership tests |
| | operator | Merges two dicts (Python 3.9+); right-side values win on conflicts |
| defaultdict | Dict subclass calling a factory for missing keys; avoids KeyError |
| Counter | dict subclass counting hashable objects; returns 0 for missing keys |
| hashable | Object that can be used as a dict key; has __hash__ and __eq__ |