23. Dictionaries

A dictionary maps keys to values. Instead of positions (0, 1, 2), you look things up by name — like looking a word up in a real dictionary.

Creating a dictionary

The literal syntax uses curly braces with "key": value pairs:

player = {
    "name": "Keiko",
    "level": 7,
    "hp": 95,
    "alive": True,
}

The trailing comma is optional, but good style: it makes adding a field a one-line diff later.

Read values with bracket notation:

print(player["name"])    # Keiko
print(player["level"])   # 7

Python does not support dot notation (player.name) for dictionaries. You always use player["name"].

When the key is held in a variable, that works too:

field = "hp"
print(player[field])   # 95

Adding and changing fields

Assigning to a missing key creates it; assigning to an existing key replaces it; del removes it:

player["mana"] = 30       # new key
player["hp"] = 100        # replace existing
del player["alive"]       # delete

After those three lines, player holds "name", "level", "hp", "mana".

Looping with .items()

.items() gives you every key-value pair in insertion order:

for key, value in player.items():
    print(key, value)

Python 3.7+ guarantees that .items() returns pairs in the order you inserted them. If you need alphabetical order, sort the keys:

for key in sorted(player.keys()):
    print(key, player[key])

Do not use for key in player: and then try to delete keys inside the loop — Python raises a RuntimeError if you change a dictionary's size while iterating. Build a list of keys to delete first, then delete them after the loop.

Checking if a key exists

Use the in operator:

if "email" in player:
    print(player["email"])
else:
    print("No email on file.")

Accessing a missing key directly raises a KeyError. The in check avoids that. Alternatively, .get(key) returns None for a missing key without raising an error:

print(player.get("email"))          # None
print(player.get("email", "n/a"))   # n/a  (default if missing)

Nested dictionaries

A dictionary value can be another dictionary (or a list) — the standard way to build structured data:

player = {
    "name": "Keiko",
    "position": {"x": 0, "y": 5, "z": -3},
    "inventory": ["sword", "potion", "map"],
}

print(player["position"]["x"])    # 0
print(player["inventory"][0])     # sword

This is exactly how game engines and web APIs pass data around.

Dictionaries and lists together

A list of dictionaries is a common pattern — a leaderboard, an item database, a save file:

quest = {
    "name": "Healer's Errand",
    "reward": 50,
    "steps": [
        "Speak to the elder",
        "Collect 5 herbs",
        "Return to camp",
    ],
}

print(quest["name"])         # Healer's Errand
print(quest["steps"][0])     # Speak to the elder
print(len(quest["steps"]))   # 3

Homework

Problem 1 — Player record

Open exercises/23/homework/01-player-record.py. Build a player dictionary with at least these four keys: "name" (string), "class" (string), "level" (number), "alive" (boolean). Then loop with for key, value in player.items(): to print every key and value, one per line.

Problem 2 — Inventory weights

Open exercises/23/homework/02-inventory-weights.py. A dictionary maps item names to weights (numbers). Compute and print the total weight.

Problem 3 — Safe lookup

Open exercises/23/homework/03-safe-lookup.py. Write a function lookup(d, key) that returns the value if the key exists, else the string "(not found)". Test it with three calls: one that hits, one that misses, and one where the key is held in a variable.

Challenge — Word frequency

Open exercises/23/homework/04-word-frequency.py. Given a list of words (some repeated), build a dictionary mapping each unique word to its count. Print the dictionary one pair per line.

Stuck or finished? Open the homework solutions page.