Lesson 12 — Key-Value Stores
Dictionaries
The Python dict is the most important data structure after the list. Fast O(1) key-based lookup, flexible values, and dict comprehensions make it indispensable.
PYTHON — Dict basics
# Creation:
learner = {
"name": "Thandi Mokoena",
"age": 21,
"course": "Python",
"mark": 74.5,
"active": True
}
# Access:
print(learner["name"]) # Thandi Mokoena
print(learner.get("city")) # None — no error
print(learner.get("city", "Unknown")) # Unknown — with default
# Add or update:
learner["city"] = "Johannesburg"
learner["mark"] = 82.0 # updates existing key
# Delete:
del learner["active"]
removed = learner.pop("age") # removes and returns the value
print(removed) # 21
PYTHON — Iterating
# Iterating:
for key in learner:
print(f"{key}: {learner[key]}")
# Preferred — iterate key-value pairs:
for key, value in learner.items():
print(f"{key}: {value}")
# Just keys or just values:
print(list(learner.keys()))
print(list(learner.values()))
# Membership test — checks keys:
print("name" in learner) # True
print("Thandi" in learner) # False — checks keys, not values
Dict Comprehensions
PYTHON — Dict comprehensions
marks = {"Thandi": 74.5, "Sipho": 81.0, "Lerato": 58.0, "Bongani": 88.5}
# Filter — only passing learners:
passing = {name: m for name, m in marks.items() if m >= 50}
print(passing)
# Transform values:
graded = {name: ("Pass" if m >= 50 else "Fail")
for name, m in marks.items()}
print(graded)
# Create from two lists (zip):
names = ["Thandi", "Sipho", "Lerato"]
scores = [74.5, 81.0, 58.0]
mark_dict = dict(zip(names, scores))
print(mark_dict)
Nested Dicts and defaultdict
PYTHON — Nested dicts
from collections import defaultdict
# Nested dict — learner profiles by course:
cohort = {
"Java": [{"name": "Thandi", "mark": 74.5}],
"Python": [{"name": "Sipho", "mark": 81.0}]
}
cohort["SQL"] = [{"name": "Lerato", "mark": 68.0}]
print(cohort["Java"][0]["name"]) # Thandi
# defaultdict — auto-creates missing keys:
by_course = defaultdict(list) # default is an empty list
for name, course, mark in [
("Thandi","Java",74.5),("Sipho","Python",81.0),
("Lerato","Java",68.0),("Bongani","SQL",88.5)]:
by_course[course].append({"name": name, "mark": mark})
for course, learners in by_course.items():
avg = sum(l["mark"] for l in learners) / len(learners)
print(f"{course}: {len(learners)} learners, avg {avg:.1f}%")
Practice Task
Your Turn
Build a word frequency counter: given a string of text, create a dict mapping each word to its count. Sort by frequency descending and print the top 10 words. Then create a dict of course: list_of_learners from a flat list of (name, course, mark) tuples. Compute and print the average mark per course.
Common Mistakes
d[key]raises KeyError — always used.get(key)or check withkey in dfirst.- Dict keys must be hashable — lists and dicts cannot be keys.
- Iterating a dict and modifying it simultaneously — RuntimeError. Use a copy:
dict(d). - defaultdict changes how missing keys behave — don't forget you're using one.
Professional Tip
Dictionaries are how Python represents structured data — JSON, configuration, database rows, function keyword arguments. Mastering dicts is essential for every Python domain.
Mini Quiz
What does dict.get('key') return if 'key' does not exist?
dict.get(key) returns None by default if the key is absent. dict.get(key, default) returns your chosen default instead.