Learn Python / Dictionaries

Dictionaries

A list finds items by position: scores[0], scores[1]. Often it's much more natural to find things by name: a word's definition, a user's email, a product's price. A dictionary stores key-value pairs, so you look up a value using its key.

Creating a dictionary

Write key: value pairs inside curly braces:

person = {
    "name": "Ada",
    "age": 36,
    "city": "London",
}

print(person)
print(type(person))
print(len(person))   # number of pairs
Output

Keys are usually strings, but they can be numbers or tuples too. Each key appears only once in a dictionary. Values can be anything, including lists or other dictionaries.

Looking up values

Put the key in square brackets:

person = {"name": "Ada", "age": 36, "city": "London"}

print(person["name"])
print(person["age"])
Output

Asking for a key that doesn't exist raises a KeyError:

person = {"name": "Ada", "age": 36}
print(person["email"])
Output

Safer lookups with get()

get() returns None instead of crashing, or a default value that you choose:

person = {"name": "Ada", "age": 36}

print(person.get("name"))
print(person.get("email"))
print(person.get("email", "no email"))
Output

Use in to check whether a key exists:

person = {"name": "Ada", "age": 36}

print("age" in person)
print("email" in person)
Output

Adding and changing entries

Assigning to a key adds it if it's new, or replaces its value if it already exists:

stock = {"apples": 10, "pears": 4}

stock["bananas"] = 7     # add
stock["apples"] = 12     # update
stock["pears"] += 1      # update based on the old value

print(stock)
Output

update() adds or changes several entries at once:

stock = {"apples": 10}
stock.update({"pears": 3, "apples": 15})
print(stock)
Output
Going deeper: Merging dictionaries optional

update() changes a dictionary in place. To build a new merged dictionary instead, use the | operator. When both sides have the same key, the value on the right wins:

defaults = {"theme": "light", "font_size": 14}
choices = {"font_size": 18}

settings = defaults | choices
print(settings)
print(defaults)    # unchanged
Output

You may also see the older spelling {**defaults, **choices}, which does the same thing.

Removing entries

stock = {"apples": 10, "pears": 4, "bananas": 7, "kiwis": 2}

removed = stock.pop("pears")    # remove and return the value
print(removed, stock)

del stock["bananas"]            # remove
print(stock)

stock.clear()                   # remove everything
print(stock)
Output

Keys, values and items

Three methods give you views of the dictionary's contents:

prices = {"coffee": 3.5, "tea": 2.8, "juice": 4.0}

print(list(prices.keys()))
print(list(prices.values()))
print(list(prices.items()))   # list of (key, value) tuples
Output

These come in handy for calculations:

prices = {"coffee": 3.5, "tea": 2.8, "juice": 4.0}

print(sum(prices.values()))
print(max(prices.values()))
print(sorted(prices))         # sorted keys
Output

You'll loop over these in the For Loops lesson, which is where dictionaries really shine.

Counting with a dictionary

A very common pattern is counting things. get(key, 0) gives 0 the first time a key is seen:

votes = {}

votes["red"] = votes.get("red", 0) + 1
votes["blue"] = votes.get("blue", 0) + 1
votes["red"] = votes.get("red", 0) + 1

print(votes)
Output
Going deeper: Counting the easy way with Counter optional

Counting is so common that Python has a ready-made tool for it. Counter from the collections module counts everything in a list in one step:

from collections import Counter

votes = ["red", "blue", "red", "green", "red", "blue"]
counts = Counter(votes)

print(counts)
print(counts["red"])
print(counts["purple"])        # missing keys count as 0, no KeyError
print(counts.most_common(2))   # the two most common, as (value, count) pairs
Output

A Counter is a dictionary underneath, so everything from this lesson still works on it.

Going deeper: Dictionaries inside dictionaries optional

Values can be lists or other dictionaries, which lets you model structured data:

student = {
    "name": "Mia",
    "grades": [88, 92, 79],
    "address": {
        "city": "Leeds",
        "postcode": "LS1 4AP",
    },
}

print(student["grades"][1])
print(student["address"]["city"])

student["grades"].append(95)
print(student["grades"])
Output

This is exactly the shape of JSON, the format most web APIs use to send data.

Going deeper: What can be a key? optional

Keys must be immutable: strings, numbers and tuples work, but lists don't:

distances = {("London", "Paris"): 344}
print(distances[("London", "Paris")])

bad = {["a", "b"]: 1}
Output

Exercises

Exercise 1: Contact card

Create a dictionary for a contact with keys name, phone and email, then print the phone number.

contact = {}
Output

Exercise 2: Update the inventory

Sell 3 apples, add a new item "mangos" with 6 in stock, and remove "pears". It should print {'apples': 7, 'bananas': 5, 'mangos': 6}.

inventory = {"apples": 10, "pears": 4, "bananas": 5}

print(inventory)
Output

Exercise 3: Safe lookup

Look up the capital of country. If the country isn't in the dictionary, print Unknown instead of crashing.

capitals = {"France": "Paris", "Japan": "Tokyo", "Kenya": "Nairobi"}
country = "Brazil"
Output

Exercise 4: Order total

The order dictionary maps items to quantities, and prices maps items to prices. Calculate the total for coffee and cake and print Total: 12.0.

prices = {"coffee": 3.0, "cake": 4.5, "tea": 2.5}
order = {"coffee": 1, "cake": 2}
Output

Dictionary methods at a glance

Each example starts from d = {"a": 1, "b": 2}. The Result column shows what the method gives back, or what d looks like afterwards for methods that change it.

Method What it does Example Result
get(key, default) Value for key, or default (None if not given) when missing d.get("c", 0) 0
keys() All the keys list(d.keys()) ['a', 'b']
values() All the values list(d.values()) [1, 2]
items() All the pairs, as (key, value) tuples list(d.items()) [('a', 1), ('b', 2)]
update(other) Adds or replaces entries from another dictionary d.update({"b": 5, "c": 3}) {'a': 1, 'b': 5, 'c': 3}
pop(key, default) Removes key and returns its value (KeyError if missing and no default) d.pop("a") returns 1, leaves {'b': 2}
popitem() Removes and returns the most recently added pair d.popitem() returns ('b', 2), leaves {'a': 1}
setdefault(key, value) Returns the value for key; if it's missing, adds it with value first d.setdefault("c", 0) returns 0, leaves {'a': 1, 'b': 2, 'c': 0}
copy() Returns a new (shallow) copy d.copy() {'a': 1, 'b': 2}
clear() Removes every entry d.clear() {}
dict.fromkeys(keys, value) A new dictionary with every key set to value dict.fromkeys(["x", "y"], 0) {'x': 0, 'y': 0}

Useful operations that aren't methods:

Operation What it does Example Result
d[key] Value for key (KeyError if missing) d["b"] 2
d[key] = value Adds or replaces an entry d["c"] = 3 {'a': 1, 'b': 2, 'c': 3}
del d[key] Removes an entry del d["a"] {'b': 2}
key in d Is key in the dictionary? "a" in d True
len(d) Number of entries len(d) 2
d | other A new merged dictionary d | {"c": 3} {'a': 1, 'b': 2, 'c': 3}

Summary

  • A dictionary maps keys to values: {"name": "Ada"}.
  • Look up values with d[key]. A missing key raises KeyError. Use d.get(key, default) to be safe.
  • d[key] = value adds or updates. pop() and del remove.
  • keys(), values() and items() give you the contents.