Dictionaries
A list finds things by position: item 0, item 1. A dictionary finds things by name. It stores pairs: a key, and the value that goes with it. Write them between curly braces as key: value, separated by commas.
1stock = {"coal": 40, "iron": 12, "gold": 3}2print(stock)3print(stock["iron"])4print(len(stock))5print(type(stock))
{'coal': 40, 'iron': 12, 'gold': 3}
12
3
<class 'dict'>
Think of a warehouse ledger: look up "iron", read 12. len counts the pairs. Keys are usually strings, but numbers work too; values can be anything, including lists.
Looking up a value
dict[key] gives the value for that key. Keys are exact: "Iron" and "iron" are different keys. Ask for a key that is not there and Python stops with a KeyError, naming the missing key.
1stock = {"coal": 40, "iron": 12, "gold": 3}2print(stock["gold"])3print(stock["silver"])
3
Traceback (most recent call last):
File "main.py", line 3, in <module>
print(stock["silver"])
KeyError: 'silver'in checks whether a key is in the dictionary. It does not look at the values.
1stock = {"coal": 40, "iron": 12, "gold": 3}2print("coal" in stock)3print(40 in stock)4if "silver" in stock:5 print(stock["silver"])6else:7 print("No silver yet")
True False No silver yet
get(): a safe lookup
get(key) is like dict[key], but a missing key gives None instead of an error. Give it a second value and you get that instead of None.
1stock = {"coal": 40, "iron": 12}2print(stock.get("coal"))3print(stock.get("silver"))4print(stock.get("silver", 0))
40 None 0
Use dict[key] when the key must be there, so a mistake shows up as an error. Use get when a missing key is normal.
Adding and changing
dict[key] = value does two jobs. If the key is new, it adds a pair. If the key is already there, it replaces the value. A key can appear only once.
1stock = {"coal": 40}2stock["iron"] = 123print(stock)4stock["coal"] = 355print(stock)6stock["coal"] = stock["coal"] + 57print(stock)8stock.update({"gold": 3, "iron": 20})9print(stock)
{'coal': 40, 'iron': 12}
{'coal': 35, 'iron': 12}
{'coal': 40, 'iron': 12}
{'coal': 40, 'iron': 20, 'gold': 3}
update adds or replaces several pairs at once, from another dictionary. Dictionaries remember the order you added the keys in; changing a value does not move it.
Removing
del dict[key] deletes a pair. pop(key) deletes it and gives you the value. Both are a KeyError if the key is missing, unless you give pop a second value to use instead.
1stock = {"coal": 40, "iron": 12, "gold": 3}2del stock["coal"]3print(stock)4gold = stock.pop("gold")5print(gold, stock)6print(stock.pop("silver", 0))
{'iron': 12, 'gold': 3}
3 {'iron': 12}
0
clear() empties the whole dictionary.
keys, values, items
keys() gives all the keys, values() all the values, and items() all the pairs as (key, value) tuples. Wrap them in list() to see them as plain lists. sum, max, sorted and in work on them too.
1stock = {"coal": 40, "iron": 12, "gold": 3}2print(list(stock.keys()))3print(list(stock.values()))4print(list(stock.items()))5print("Total ore:", sum(stock.values()))6print(sorted(stock))
['coal', 'iron', 'gold']
[40, 12, 3]
[('coal', 40), ('iron', 12), ('gold', 3)]
Total ore: 55
['coal', 'gold', 'iron']
sorted(stock) sorts the keys: when you use a dictionary directly, as with in or sorted, you get its keys. In lesson 13, a for loop will walk through these one pair at a time.
What does this print?
1d = {"a": 1, "b": 2}2d["a"] = 33d["c"] = 14print(len(d), sum(d.values()))
d["a"] = 3 replaces the value of "a"; it does not add a new pair. So there are three keys, a, b, c, and the values are 3 + 2 + 1 = 6.
Counting with a dictionary
A dictionary is a natural tally: the thing is the key, its count is the value. The trick is get(key, 0) + 1: the first time, get gives 0, so the count starts at 1.
1found = "iron coal iron gold iron".split()2counts = {}3counts[found[0]] = counts.get(found[0], 0) + 14counts[found[1]] = counts.get(found[1], 0) + 15counts[found[2]] = counts.get(found[2], 0) + 16print(counts)
{'iron': 2, 'coal': 1}
Press Step and watch counts grow: iron appears, then coal, then iron goes up to 2. Writing one line per word gets long; in lesson 13 a for loop does this for any number of words in two lines.
Tip: counts.get(word, 0) + 1 works whether or not the word has been seen before. counts[word] + 1 fails with a KeyError the first time.
What can be a key
A key must be a value that cannot change: a string, a number, a boolean, or a tuple of these. A list can change, so it cannot be a key. Python calls such values unhashable.
1lamps = {(4, 7): "lit", (2, 3): "dark"}2print(lamps[(4, 7)])3bad = {["coal"]: 1}
lit
Traceback (most recent call last):
File "main.py", line 3, in <module>
bad = {["coal"]: 1}
TypeError: unhashable type: 'list'Values have no such rule. A value can be a list, or even another dictionary.
Methods at a glance
| Write | What it does |
|---|---|
d[k] | the value for k (KeyError if missing) |
d.get(k) / d.get(k, x) | the value, or None / x if missing |
d[k] = v | adds the pair, or replaces the value |
d.update(other) | adds or replaces every pair of other |
del d[k] | deletes the pair |
d.pop(k) / d.pop(k, x) | deletes and gives back the value / x if missing |
d.clear() | deletes everything |
k in d | is k a key? |
d.keys(), d.values(), d.items() | the keys, the values, the (key, value) pairs |
len(d) | how many pairs |
Practice
Write the code, then press Check. A hint costs nothing; the answer is there when you need it.
A delivery
✓A cart brings 8 more iron and the first 5 silver. Update stock so it prints as shown.
{'coal': 40, 'iron': 20, 'silver': 5}1stock = {"coal": 40, "iron": 12}2# Your code here3print(stock)
Ask nicely
✓Print the number of lamps on each street. Hill Street is not in the dictionary, so it should show 0, without an error.
2 0
1lamps = {"Mill Lane": 4, "Pond Road": 2}2print(lamps["Pond Road"])3print(lamps["Hill Street"])
Tally the ore
✓Count the three finds into counts with get, then print it.
{'gold': 2, 'coal': 1}1finds = ["gold", "coal", "gold"]2counts = {}3# Your code here4print(counts)
What you learned
- A dictionary stores
key: valuepairs:{"coal": 40}.d[key]looks up a value. - A missing key is a
KeyError;get(key, default)avoids it.inchecks the keys. d[key] = valueadds or replaces;del,popandclearremove.keys(),values()anditems()give the keys, the values and the pairs.d[k] = d.get(k, 0) + 1counts things.- Keys must be values that cannot change, such as strings, numbers and tuples, never lists.