Dictionaries

The Course
•
January 7, 2026
•
5 min read

A dictionary maps keys to values. Where a list answers “what is at position 2?”, a dictionary answers “what is the capital of France?”.

Keys and values Python
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:

get() never raises Python
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.

Building a dictionary up Python
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

Three ways round a dictionary Python
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.

Counting words Python
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.

Structured data Python
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.

What will this print? Python
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 True

Assigning 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.

Counting from nothing Python
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.

Exercise

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 Japan
capitals = {
    "France": "Paris",
    "Japan": "Tokyo",
    "Peru": "Lima",
}

# Your code here
Hint 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] raises KeyError when missing; d.get(key, default) does not.
  • Assigning to a new key creates it; del removes one.
  • Loop with .items() and unpack into two names.
  • d.get(k, 0) + 1 is the counting idiom.
Last updated on January 7, 2026

Was this article helpful?

Your response is saved on this device.