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.
Before you write your own
Predict. Three lines, including the whole dictionary.
stock = {"pens": 4, "paper": 10}
stock["pens"] += 2
stock["tape"] = 1
print(stock)
print(stock.get("glue", 0))
print(len(stock), "paper" in stock)Check your prediction
{'pens': 6, 'paper': 10, 'tape': 1}
0
3 TrueAssigning to a new key ("tape") adds it at the end, because dictionaries keep
insertion order. get with a default never raises, and in asks about keys.
Fix. Count the survey answers. It should print
{'yes': 3, 'no': 1, 'maybe': 1}, and it crashes on the very first answer.
answers = ["yes", "no", "yes", "maybe", "yes"]
counts = {}
for answer in answers:
counts[answer] += 1
print(counts)Check your fix
answers = ["yes", "no", "yes", "maybe", "yes"]
counts = {}
for answer in answers:
counts[answer] = counts.get(answer, 0) + 1
print(counts){'yes': 3, 'no': 1, 'maybe': 1}counts[answer] += 1 has to read counts["yes"] before it can add to it, and
the first time there’s nothing to read: KeyError. get(answer, 0) treats a
missing answer as zero.
Invert a dictionary
Given a dictionary of country → capital, build and print the reverse mapping, capital → country. Then print the capitals in alphabetical order. Your output should be:
{'Paris': 'France', 'Tokyo': 'Japan', 'Lima': 'Peru'}
Lima is the capital of Peru
Paris is the capital of France
Tokyo is the capital of Japancapitals = {
"France": "Paris",
"Japan": "Tokyo",
"Peru": "Lima",
}
# Your code hereHint 1: the idea
Start with an empty dictionary and fill it as you loop over the original. Each pair turns round: the capital becomes the new key, and the country its value.
Hint 2: a first step
for country, capital in capitals.items(): gives you both halves of each pair.
Inside, one assignment adds the reversed pair to your new dictionary. For the
alphabetical part: sorted() on a dictionary gives you its keys in order.
Show 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.