A dictionary maps keys to values. Where a list answers “what is at position 2?”, a dictionary answers “what is the capital of France?”.
person = {
"name": "Ada",
"born": 1815,
"field": "mathematics",
}
print(person["name"])
print(person["born"])
print(len(person))
print("field" in person)
# Missing keys raise an error:
print(person["email"])KeyError: 'email'. Loud and immediate, which is what you want — but often you
would rather have a fallback:
person = {"name": "Ada", "born": 1815}
print(person.get("email")) # None
print(person.get("email", "not provided")) # your own default
print(person.get("name", "unknown"))Adding and changing
Dictionaries are mutable. Assigning to a key that does not exist creates it.
stock = {}
stock["apples"] = 12
stock["pears"] = 3
stock["apples"] += 5 # update an existing key
print(stock)
del stock["pears"]
print(stock)
# Merge another dictionary in:
stock.update({"figs": 7, "apples": 20})
print(stock)Keys must be immutable — strings, numbers and tuples work; lists do not. Values can be anything at all, including other dictionaries.
Looping
prices = {"coffee": 3.50, "tea": 2.75, "juice": 4.00}
for name in prices: # keys, by default
print(name)
print("---")
for price in prices.values():
print(price)
print("---")
for name, price in prices.items(): # both, unpacked
print(f"{name:8} ${price:.2f}").items() with unpacking is the one you will write most. Since Python 3.7,
dictionaries keep their insertion order, so these loops are predictable.
Counting things
Counting occurrences is the classic dictionary job, and worth writing out once before you use the shortcut.
text = "the quick brown fox jumps over the lazy dog the end"
counts = {}
for word in text.split():
counts[word] = counts.get(word, 0) + 1
print(counts)
# Sort by count, highest first:
ranked = sorted(counts.items(), key=lambda pair: pair[1], reverse=True)
print(ranked[:3])counts.get(word, 0) + 1 is the trick: treat a missing word as zero, add one,
store it back. The standard library also ships collections.Counter, which does
all of this in one line — you will meet it on Day 5.
Nesting
Real data is usually dictionaries inside dictionaries inside lists — this is exactly the shape JSON arrives in.
library = {
"name": "City Library",
"books": [
{"title": "Dune", "year": 1965, "tags": ["scifi", "classic"]},
{"title": "Piranesi", "year": 2020, "tags": ["fantasy"]},
],
}
print(library["name"])
print(library["books"][0]["title"])
print(library["books"][0]["tags"][1])
for book in library["books"]:
tags = ", ".join(book["tags"])
print(f"{book['title']} ({book['year']}) - {tags}")Quotes inside f-strings
Note {book['title']} — single quotes inside a double-quoted f-string. Match
the same quote character and Python will end the string early.
Invert a dictionary
Given a dictionary of country → capital, build and print the reverse mapping, capital → country. Then print the capitals in alphabetical order.
capitals = {
"France": "Paris",
"Japan": "Tokyo",
"Peru": "Lima",
}
# Your code hereShow one solution
capitals = {
"France": "Paris",
"Japan": "Tokyo",
"Peru": "Lima",
}
countries = {}
for country, capital in capitals.items():
countries[capital] = country
print(countries)
for capital in sorted(countries):
print(f"{capital} is the capital of {countries[capital]}")Inverting only works cleanly when the values are unique — two countries sharing a capital would silently lose one. Worth a thought whenever you flip a mapping.
What you learned
- A dictionary maps immutable keys to any values, written
{key: value}. d[key]raisesKeyErrorwhen missing;d.get(key, default)does not.- Assigning to a new key creates it;
delremoves one. - Loop with
.items()and unpack into two names. d.get(k, 0) + 1is the counting idiom.