Dictionaries in Python
A dictionary stores key-value pairs, so you look values up by a name instead of a position. You write the pairs in curly braces, such as {"Ada": 36}, read a value with ages["Ada"] or ages.get("Ada"), and add a pair by assigning to a new key. Dictionaries keep the order the keys were added in.
Key facts
ages = {"Ada": 36}maps the key"Ada"to the value 36. Keys are unique.ages["Ada"]returns the value, and a missing key raisesKeyError.ages.get("Bob")returnsNoneinstead.ages["Bob"] = 28adds a new pair or replaces the value of an existing key.- A for loop over a dictionary gives its keys.
ages.items()gives each key with its value. - Dictionaries keep the order the keys were added in, and a key must be a value that cannot change, so a list cannot be a key.
What is a dictionary in Python?
A dictionary stores key-value pairs, so you look values up by a name instead of a position. You write the pairs inside curly braces, with a colon between each key and its value, and the dict type keeps them in the order you added them. A dictionary is the natural type for a record with named fields, a lookup table, or a count of how often things occur.
ages = {"Ada": 36, "Bob": 28}
print(ages)
print(type(ages))
print(len(ages))
print(ages["Ada"]){'Ada': 36, 'Bob': 28}
<class 'dict'>
2
36ages["Ada"] asks for the value stored under the key "Ada", the way fruits[0] asks a list for the item at position 0. Keys are unique, so a dictionary holds one value per key, and len() counts the pairs. Python programmers say dict as often as dictionary, and the two words mean the same thing.
How do I create a dictionary in Python?
Write key: value pairs inside curly braces, separated by commas. Empty braces make an empty dictionary, and dict(name="Ada", age=36) builds one from name=value arguments. Keys must be values that can't change, such as strings, numbers or tuples, and values can be anything, including lists and other dictionaries.
empty = {}
print(empty)
person = dict(name="Ada", age=36)
print(person)
mixed = {1: "one", "two": 2, (3, 4): "point"}
print(mixed)
student = {"name": "Ada", "grades": [90, 85]}
print(student["grades"][0]){}
{'name': 'Ada', 'age': 36}
{1: 'one', 'two': 2, (3, 4): 'point'}
90The keys in mixed are a number, a string and a tuple, and each one works because none of them can change. A tuple works as a key only while everything inside it can't change either. The last line reads a value that is a list and then indexes into it, one pair of brackets per step.
A list can't be a key, because its contents could change after the dictionary has filed it. Python calls a value hashable when it can turn it into a fixed number, which it can do for any value that can't change, and unhashable is the word in the error message when a list is tried as a key.
How do I get a value from a dictionary?
Put the key in square brackets, or call get(). Square brackets raise KeyError when the key is missing, and get() returns None instead, or a default value you pass as its second argument. The in operator tests whether a key exists.
ages = {"Ada": 36, "Bob": 28}
print(ages["Bob"])
print(ages.get("Bob"))
print(ages.get("Cy"))
print(ages.get("Cy", 0))
print("Ada" in ages)
print("Cy" in ages)28 28 None 0 True False
Use the brackets when the key must exist and a missing one is a bug worth stopping for. Use get() when a missing key is normal, such as counting words you haven't seen before. in looks at keys only, so 36 in ages is False even though 36 is a value.
| Form | What you get | Use it when |
|---|---|---|
d[key] | The value, or KeyError when the key is missing | The key must exist |
d.get(key) | The value, or None when the key is missing | A missing key is normal |
d.get(key, default) | The value, or the default when the key is missing | You need a stand-in value, such as 0 for a count |
A lookup with a default also replaces an if and elif chain that maps each case to one value, which is the dictionary lookup the match statement lesson mentioned.
messages = {200: "OK", 404: "Not found"}
print(messages.get(404, "Unknown status"))
print(messages.get(418, "Unknown status"))Not found Unknown status
How do I add a key or change its value in a dictionary?
Assign a value to the key in square brackets. When the key is new, the assignment adds the pair at the end. When the key exists, the assignment replaces its value, and the pair keeps its place. update() does the same for several pairs at once.
ages = {"Ada": 36, "Bob": 28}
ages["Cy"] = 41
print(ages)
ages["Bob"] = 29
print(ages)
ages.update({"Dee": 25, "Ada": 37})
print(ages)
print(len(ages)){'Ada': 36, 'Bob': 28, 'Cy': 41}
{'Ada': 36, 'Bob': 29, 'Cy': 41}
{'Ada': 37, 'Bob': 29, 'Cy': 41, 'Dee': 25}
4There is no append() on a dictionary, because a pair is added by assigning to its key, not by pushing it onto the end. The update() call added "Dee" and changed "Ada" in one step, and the length rose by one, since "Ada" was already there.
How do I remove a key from a dictionary?
Use del with the key in brackets, or call pop() with the key. pop() returns the value it removed, and a second argument makes it return that default instead of raising KeyError for a missing key.
ages = {"Ada": 36, "Bob": 28, "Cy": 41}
del ages["Bob"]
print(ages)
removed = ages.pop("Cy")
print(removed)
print(ages)
print(ages.pop("Zed", "nobody")){'Ada': 36, 'Cy': 41}
41
{'Ada': 36}
nobodyclear() empties the whole dictionary, and popitem() removes and returns the pair that was added last.
How do I loop through a dictionary in Python?
A for loop over a dictionary gives you its keys, one per pass. Call values() to loop over the values instead, and items() to get each key and value together as a pair you can unpack into two names.
ages = {"Ada": 36, "Bob": 28}
for name in ages:
print(name)
for age in ages.values():
print(age)
for name, age in ages.items():
print(name, "is", age)
print(ages.keys())Ada Bob 36 28 Ada is 36 Bob is 28 dict_keys(['Ada', 'Bob'])
The items() loop is the one you will use most, because a key on its own usually needs its value. The last line shows what keys() returns, a view printed as dict_keys([...]). A view is a live window onto the dictionary's keys rather than a copy, and list(ages.keys()) turns it into a list.
Every loop over a dictionary runs in the order the keys were added, which Python has guaranteed since version 3.7.
Counting is the classic dictionary loop, and get() with a default of 0 handles the first time a word shows up.
words = ["red", "blue", "red", "green", "red"]
counts = {}
for word in words:
counts[word] = counts.get(word, 0) + 1
print(counts){'red': 3, 'blue': 1, 'green': 1}Which dictionary methods does Python have?
Python dictionaries have eleven methods, and the table lists all of them. len() counts the pairs, and sorted(ages) returns the keys in order, because a dictionary hands out its keys to anything that loops over it, and sorted() loops.
| Method | What it does |
|---|---|
clear() | Removes every pair |
copy() | Returns a new dictionary with the same pairs |
fromkeys(keys, value) | Builds a dictionary with each key set to the same value, None by default |
get(key, default) | Returns the value for key, or the default when the key is missing, and the default is None unless you pass one |
items() | Returns the pairs as (key, value) tuples for looping |
keys() | Returns the keys for looping |
pop(key, default) | Removes key and returns its value, or the default when it is missing |
popitem() | Removes and returns the pair added last |
setdefault(key, default) | Returns the value for key, first adding the key with the default when it is missing |
update(other) | Adds or replaces pairs from another dictionary, a list of (key, value) pairs, or name=value arguments |
values() | Returns the values for looping |
A dictionary comprehension, {n: n * n for n in range(4)}, builds a dictionary the way a list comprehension builds a list, with a key and a value in the expression.
What is the difference between a list and a dictionary?
A list stores items by position, and a dictionary stores values by key. Use a list when the order is the point or the items have no natural name, and a dictionary when each value has a name you will look it up by.
| Type | Written as | Read by | Use it when |
|---|---|---|---|
| List | Square brackets, ["Ada", "Bob"] | Position, names[0] | The values are an ordered sequence of similar items |
| Dictionary | Curly braces, {"Ada": 36} | Key, ages["Ada"] | Each value has a name, such as fields, lookups and counts |
Finding a key in a dictionary takes about the same time however many pairs it holds, while finding a value in a list means checking the items one by one. That is why a dictionary is the tool for lookups, and a set, which the next lesson covers, gives the same fast test without the values.
What is a nested dictionary in Python?
A nested dictionary is a dictionary whose values are dictionaries. One pair of brackets picks the inner dictionary and a second pair picks a value inside it, so people["ada"]["city"] reads the city of the record filed under "ada".
people = {
"ada": {"age": 36, "city": "London"},
"bob": {"age": 28, "city": "Paris"},
}
print(people["ada"]["city"])
people["bob"]["age"] = 29
print(people["bob"])
for key, info in people.items():
print(key, info["age"])London
{'age': 29, 'city': 'Paris'}
ada 36
bob 29Data from the web arrives in this shape, because JSON, the text format most websites use to send data, maps its objects onto dictionaries and its arrays onto lists. The JSON to Python converter shows the Python code for any JSON you paste in, and a later lesson covers reading JSON in code.
Common mistakes with dictionaries in Python
Each of these four mistakes with dictionaries usually stops the program with a message that names the problem.
- KeyError: 'Bob'. The key isn't in the dictionary. Check with
in, or read withget()and a default. - TypeError: cannot use 'list' as a dict key (unhashable type: 'list'). A list was used as a key, and a list can change, so it isn't hashable. Use a tuple or a string.
- ValueError: too many values to unpack (expected 2). The loop was written as
for name, age in ages:withoutitems(), so each pass received only a key and tried to split it in two. A key that happens to be two characters long even splits silently into its letters. Add.items(). - AttributeError: 'dict' object has no attribute 'append'. A dictionary has no
append(). Assign to a new key instead.
Run the three broken programs to see the messages, then fix them in the editor.
ages = {"Ada": 36}
print(ages["Bob"])Traceback (most recent call last):
File "main.py", line 2, in <module>
print(ages["Bob"])
~~~~^^^^^^^
KeyError: 'Bob'prices = {[1, 2]: "pair"}Traceback (most recent call last):
File "main.py", line 1, in <module>
prices = {[1, 2]: "pair"}
^^^^^^^^^^^^^^^^
TypeError: cannot use 'list' as a dict key (unhashable type: 'list')ages = {"Ada": 36, "Bob": 28}
for name, age in ages:
print(name, age)Traceback (most recent call last):
File "main.py", line 2, in <module>
for name, age in ages:
^^^^^^^^^
ValueError: too many values to unpack (expected 2)Exercise
Add "Grace" with the age 45, change the age of "Linus" to 29, and keep the loop, so the program prints Ada is 36, Linus is 29 and Grace is 45 on three lines. The starter prints the two people already in the dictionary.
ages = {"Ada": 36, "Linus": 28}
for name, age in ages.items():
print(name, "is", age)
Ada is 36 Linus is 29 Grace is 45
Show the solution
ages = {"Ada": 36, "Linus": 28}
ages["Grace"] = 45
ages["Linus"] = 29
for name, age in ages.items():
print(name, "is", age)
Quiz
This quiz has 5 questions. Pick an answer to see why it is right or wrong.
-
1What does this program print?
d = {"a": 1} print(d.get("b"))get() returns None when the key is missing and no default was given. Square brackets would have raised KeyError instead.
-
2What happens when a program runs print(d["b"]) and "b" is not a key in d?
Square brackets raise KeyError for a missing key. Only get() returns None, and reading never adds a key.
-
3What does this program print?
d = {"x": 1, "y": 2} for k in d: print(k)A for loop over a dictionary gives its keys. The values need d.values(), and both together need d.items().
-
4Which expression creates an empty dictionary?
Empty curly braces make an empty dictionary. Square brackets make a list, parentheses make a tuple, and set() makes an empty set.
-
5What does this program print?
d = {"a": 1} d["a"] = 5 print(d, len(d))Assigning to an existing key replaces its value, so the dictionary still has one pair and it now holds 5. Keys are unique, so a second "a" key can never appear.