Know some Python? Write your own interactive tutorial, with runnable examples and exercises, and share it with a link. Write and share your own tutorial.

Start writing

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

Each pair is a key, a colon, then its value, and the pairs are separated by commas. Keys are usually strings, but they can be numbers or tuples too. Values can be anything, including lists or other dictionaries.

A few rules to know:

  • Each key appears only once. If you write the same key twice, the last value wins.
  • Keys are case-sensitive: "name" and "Name" are different keys.
  • The pairs stay in the order you added them.
  • {} is an empty dictionary.

Looking up values

Put the key in square brackets:

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

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

Lookups only work in one direction: from a key to its value. There's no person["Ada"] to find the key from a value. That's why you choose the thing you'll search by as the key.

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

in checks the keys, not the values: "Ada" in person is False.

You write If the key exists If it's missing
person["email"] its value KeyError
person.get("email") its value None
person.get("email", "no email") its value "no email"
"email" in person True False

None of these add the key to the dictionary; they only read it.

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}

# new key: added
stock["bananas"] = 7

# existing key: replaced
stock["apples"] = 12

# add 1 to the current value
stock["pears"] += 1

print(stock)
Output

The same syntax adds or updates, so there's no separate "add" method. += needs a current value, though: stock["kiwis"] += 1 is a KeyError because there are no kiwis yet. That's the problem the counting pattern below solves.

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}

# remove a key and give back its value
removed = stock.pop("pears")
print(removed, stock)

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

# remove everything
stock.clear()
print(stock)
Output
Use Removes Missing key
d.pop(key) that key, and gives back its value KeyError
d.pop(key, default) that key, and gives back its value gives back default, no error
del d[key] that key KeyError
d.clear() every key (never fails)

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()))
Output
  • keys() gives the keys, values() the values, and items() each pair as a (key, value) tuple.
  • They're wrapped in list() here only so they print neatly; on their own they print as dict_keys([...]) and so on.
  • They follow the dictionary's order, so the first key, first value and first item all belong together.

These come in handy for calculations:

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

print(sum(prices.values()))
print(max(prices.values()))

# a dictionary on its own means its keys
print(sorted(prices))
Output

max(prices.values()) gives the highest price, 4.0, not which drink it is. When you pass the dictionary itself, as in sorted(prices), Python uses the keys.

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
Line get() gives Stored votes afterwards
1st (red) 0 (not there yet) 0 + 1 = 1 {'red': 1}
2nd (blue) 0 (not there yet) 0 + 1 = 1 {'red': 1, 'blue': 1}
3rd (red) 1 1 + 1 = 2 {'red': 2, 'blue': 1}

The same line works whether or not the key exists yet, which is why this pattern is everywhere.

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"])
# missing keys count as 0
print(counts["purple"])

# the two most common
print(counts.most_common(2))
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.

Share this tutorial

Know something worth teaching? Write your own tutorial with runnable examples and share it.