PythonMastery
reference 5 min read · lesson 4 of 25 in Reference

Python Dictionary Cheat Sheet

1 · The lesson

read

A dictionary (a dict) stores values under keys, so you can find a value by its key instead of by its position: a price by a product name, a score by a player name. Finding a value by its key is fast, even in a very large dictionary. Keys are unique, and they stay in the order you added them. For the full tutorial, see Dictionaries.


1. Create a dictionary

A key must be a value that cannot change, such as a string, a number or a tuple. A list cannot be a key.

python
prices = {"apple": 1.2, "pear": 0.9}
dict(name="Ada", age=36)              # {'name': 'Ada', 'age': 36}  (with name=value, each key must be a valid variable name)
dict([("a", 1), ("b", 2)])            # {'a': 1, 'b': 2}  (builds a dict from a list of pairs)
dict(zip("ab", [1, 2]))               # {'a': 1, 'b': 2}  (pairs up keys with values)
dict.fromkeys(["x", "y"], 0)          # {'x': 0, 'y': 0}  (gives every key the same starting value)
type({})                              # <class 'dict'>  ({} is an empty dict; an empty set is set())
{(0, 1): "start"}[(0, 1)]             # 'start'  (a tuple can be a key)

2. Read values

d[key] raises a KeyError when the key is missing. d.get(key) returns None instead, or a default that you choose. in checks the keys, not the values.

CodeWhen the key is thereWhen the key is missing
d[k]the valueraises KeyError
d.get(k)the valueNone
d.get(k, default)the valuedefault (d does not change)
d.setdefault(k, default)the valueadds k with default, then returns it
k in dTrueFalse
python
d = {"a": 1, "b": 2}
d["a"]               # 1
d.get("z")           # None
d.get("z", 0)        # 0
"a" in d             # True
1 in d.values()      # True  (this checks every value one by one, so it is slow on a big dict)
len(d)               # 2  (the number of keys)

3. Add and change

Assigning to a key adds it, or replaces its value if the key is already there. A key that you update keeps its place in the order.

python
d = {"a": 1, "b": 2}
d["c"] = 3                       # {'a': 1, 'b': 2, 'c': 3}
d.update({"a": 9, "e": 5})       # {'a': 9, 'b': 2, 'c': 3, 'e': 5}  (adds the pairs to d; new values replace old ones)
d.setdefault("n", 0)             # 0
list(d)                          # ['a', 'b', 'c', 'e', 'n']

4. Merge two dictionaries

a | b builds a new dict (Python 3.9 and later). When both dicts have the same key, the value from the right side wins. a |= b changes a itself instead of making a new dict.

python
a = {"x": 1, "y": 2}
b = {"y": 20, "z": 3}
a | b            # {'x': 1, 'y': 20, 'z': 3}
b | a            # {'y': 2, 'z': 3, 'x': 1}  (put a on the right to keep the values from a)
{**a, **b}       # {'x': 1, 'y': 20, 'z': 3}  (the older way to write a | b)

5. Remove keys

CodeWhat it does
d.pop(k)Removes k and returns its value. KeyError if missing
d.pop(k, default)The same, but returns default if k is missing
d.popitem()Removes the pair added last and returns it
del d[k]Removes k. KeyError if missing
d.clear()Removes everything
python
d = {"a": 1, "b": 2, "c": 3}
d.pop("a")           # 1
d.pop("z", None)     # None  (the default stops the KeyError)
d.popitem()          # ('c', 3)
del d["b"]
d                    # {}

6. Loop over a dictionary

A plain for loop gives you the keys. items() gives you each key and value together, which is the loop you will write most often. keys(), values() and items() return views. A view is not a copy: it always shows the current contents of the dict.

python
d = {"a": 1, "b": 2}
for key, value in d.items():
    print(key, value)
list(d)                  # ['a', 'b']
list(d.values())         # [1, 2]
list(d.items())          # [('a', 1), ('b', 2)]
next(iter(d))            # 'a'  (the first key)
max(d, key=d.get)        # 'b'  (the key with the biggest value)
python
a 1
b 2

7. Sort a dictionary

sorted(d) sorts the keys. To sort by value, sort d.items() with a key function that picks the value out of each pair. lambda kv: kv[1] is a small function with no name: it returns the second item of each (key, value) pair, which is the value.

python
d = {"pear": 3, "fig": 1, "kiwi": 2}
sorted(d)                                     # ['fig', 'kiwi', 'pear']
dict(sorted(d.items()))                       # {'fig': 1, 'kiwi': 2, 'pear': 3}
sorted(d.items(), key=lambda kv: kv[1])       # [('fig', 1), ('kiwi', 2), ('pear', 3)]
sorted(d, key=d.get, reverse=True)[:2]        # ['pear', 'kiwi']  (the 2 keys with the biggest values)

8. Comprehensions

A dict comprehension builds a new dictionary from a loop in one line.

python
d = {"a": 1, "b": 2, "c": 0}
{k: v * 10 for k, v in d.items()}             # {'a': 10, 'b': 20, 'c': 0}  (changes every value)
{k: v for k, v in d.items() if v}             # {'a': 1, 'b': 2}  (keeps only the pairs whose value is not 0)
{v: k for k, v in d.items()}                  # {1: 'a', 2: 'b', 0: 'c'}  (swaps keys and values)
{k: d[k] for k in ("a", "c") if k in d}       # {'a': 1, 'c': 0}  (keeps only the keys "a" and "c")

9. Count and group

Counter counts things for you. defaultdict(list) starts each missing key as an empty list, so you can append to the list without creating it first. Both come from the collections module. See Collections.

python
from collections import Counter, defaultdict
words = ["fig", "kiwi", "fig", "pear"]
Counter(words)                      # Counter({'fig': 2, 'kiwi': 1, 'pear': 1})
Counter(words).most_common(1)       # [('fig', 2)]

groups = defaultdict(list)
for w in words:
    groups[len(w)].append(w)
dict(groups)                        # {3: ['fig', 'fig'], 4: ['kiwi', 'pear']}  (the words grouped by their length)

counts = {}                         # the same count with a plain dict
for w in words:
    counts[w] = counts.get(w, 0) + 1
counts                              # {'fig': 2, 'kiwi': 1, 'pear': 1}

10. Nested dictionaries

A value can be another dict or a list. When a level may be missing, call get() on each level and give an empty dict {} as the default.

python
user = {"addr": {"city": "Oslo"}, "langs": ["py"]}
user["addr"]["city"]                  # 'Oslo'
user.get("job", {}).get("title")      # None  (no KeyError when "job" is missing)
user["langs"].append("sql")
user["langs"]                         # ['py', 'sql']

11. Views and copies

d.copy() makes a shallow copy: a new outer dict, but lists and dicts inside it are still shared. copy.deepcopy() copies everything inside too.

python
import copy
d = {"a": 1, "b": 2}
keys = d.keys()
d["c"] = 3
keys                    # dict_keys(['a', 'b', 'c'])  (the view shows the new key)
team = {"names": ["Ada"]}
c = team.copy()
c["names"].append("Grace")
team                    # {'names': ['Ada', 'Grace']}  (the inner list is shared)
deep = copy.deepcopy(team)
deep["names"].append("Linus")
team                    # {'names': ['Ada', 'Grace']}  (team did not change this time)

Common mistakes

Reading a missing key. d["z"] raises KeyError: 'z' (full error page). Use d.get("z"), or check with if "z" in d first.

Adding or removing keys while you loop. This raises RuntimeError: dictionary changed size during iteration (full error page). Loop over a copy of the keys:

python
d = {"a": 1, "b": 0, "c": 0}
for k in list(d):
    if d[k] == 0:
        del d[k]
d               # {'a': 1}

Using a list as a key. d[["x", "y"]] = 1 raises TypeError: unhashable type: 'list'. Use a tuple: d[("x", "y")] = 1.

Indexing a view. d.keys()[0] raises TypeError: 'dict_keys' object is not subscriptable. Write list(d)[0] or next(iter(d)).

Keys that are equal count as one key. 1, 1.0 and True are equal in Python, so they are the same key:

python
{1: "a", 1.0: "b", True: "c"}      # {1: 'c'}

One list shared by every key. dict.fromkeys() puts the same list object under every key:

python
g = dict.fromkeys("ab", [])
g["a"].append(1)
g                                  # {'a': [1], 'b': [1]}
g = {k: [] for k in "ab"}          # a new list for each key
g["a"].append(1)
g                                  # {'a': [1], 'b': []}

Expecting get() to store the default. d.get("tags", []).append("x") appends to a list that is never stored in d. Use d.setdefault("tags", []).append("x").

Thinking e = d makes a copy. Both names point to the same dict, so e["a"] = 0 changes d too. Use e = d.copy().

See also

Practice this

on practicepython.in

Short exercises that run in your browser and tell you what your code did, as well as whether a test passed.

Found this useful? Share it with a friend who’s learning Python.