Dictionaries

A dictionary (dict) maps keys to values: a word to its definition, a username to a profile, a product code to its price. Lookups by key are extremely fast, and dictionaries are the natural way to represent structured records — JSON data, for example, becomes nested dictionaries in Python.

Creating dictionaries

PY create.py
person = {"name": "Ana", "age": 31, "city": "Lisbon"}
empty = {}
from_pairs = dict([("a", 1), ("b", 2)])
from_kwargs = dict(width=800, height=600)

print(person)
print(from_pairs, from_kwargs)
print(len(person))
Output
{'name': 'Ana', 'age': 31, 'city': 'Lisbon'}
{'a': 1, 'b': 2} {'width': 800, 'height': 600}
3

Keys must be hashable (strings, numbers, tuples); values can be anything. Dictionaries remember the order in which keys were inserted.

Reading values

PY read.py
person = {"name": "Ana", "age": 31}

print(person["name"])
print(person.get("email"))
print(person.get("email", "not provided"))
print("age" in person, "email" in person)
Output
Ana
None
not provided
True False

Square brackets raise an error for a missing key; get returns None or a default you supply. in checks whether a key exists.

PY missing.py
person = {"name": "Ana"}
print(person["email"])
Output
Traceback (most recent call last):
  File "main.py", line 2, in <module>
    print(person["email"])
          ~~~~~~^^^^^^^^^
KeyError: 'email'

Adding, changing and removing

PY modify.py
stock = {"apples": 10, "pears": 4}

stock["plums"] = 7
stock["apples"] -= 3
print(stock)

removed = stock.pop("pears")
print(removed, stock)

del stock["plums"]
print(stock)

print(stock.pop("kiwis", 0))
Output
{'apples': 7, 'pears': 4, 'plums': 7}
4 {'apples': 7, 'plums': 7}
{'apples': 7}
0

Assigning to a key adds it or replaces its value. pop(key, default) removes and returns a value without erroring if the key is missing.

Looping

PY loop.py
prices = {"tea": 3.0, "cake": 4.5, "juice": 5.0}

for item in prices:
    print(item)

print(list(prices.values()))

for item, price in prices.items():
    print(f"{item}: ${price:.2f}")
Output
tea
cake
juice
[3.0, 4.5, 5.0]
tea: $3.00
cake: $4.50
juice: $5.00

Looping over a dictionary gives its keys; .values() gives values; .items() gives (key, value) pairs, which you'll use most.

Counting with a dictionary

PY count.py
text = "the cat and the hat and the bat"

counts = {}
for word in text.split():
    counts[word] = counts.get(word, 0) + 1

print(counts)
print(max(counts, key=counts.get))
Output
{'the': 3, 'cat': 1, 'and': 2, 'hat': 1, 'bat': 1}
the

counts.get(word, 0) + 1 is the classic counting idiom. The collections.Counter class (lesson 27) does it in one line.

Nested dictionaries

PY nested.py
users = {
    "ana": {"email": "ana@x.com", "roles": ["admin", "editor"]},
    "ben": {"email": "ben@x.com", "roles": []},
}

print(users["ana"]["email"])
print(users["ana"]["roles"][0])

users["ben"]["roles"].append("viewer")
for name, info in users.items():
    print(f"{name}: {', '.join(info['roles']) or 'no roles'}")
Output
ana@x.com
admin
ana: admin, editor
ben: viewer

Merging dictionaries

PY merge.py
defaults = {"theme": "light", "font_size": 14, "autosave": True}
user_prefs = {"theme": "dark"}

settings = defaults | user_prefs
print(settings)

defaults |= {"font_size": 16}
print(defaults["font_size"])

combined = {**defaults, **user_prefs, "lang": "en"}
print(combined)
Output
{'theme': 'dark', 'font_size': 14, 'autosave': True}
16
{'theme': 'dark', 'font_size': 16, 'autosave': True, 'lang': 'en'}

With | and ** unpacking, later values win. |= updates a dictionary in place, like .update().

Keys must be hashable

PY keys.py
locations = {(38.7, -9.1): "Lisbon", (41.1, -8.6): "Porto"}
print(locations[(38.7, -9.1)])

print({1: "int", 1.0: "float", True: "bool"})
Output
Lisbon
{1: 'bool'}

Tuples make good composite keys. The second line shows a curiosity: 1, 1.0 and True are equal and hash the same, so they count as one key.

Dictionary views

keys(), values() and items() return live views that reflect later changes, and key views support set operations:

PY views.py
a = {"x": 1, "y": 2, "z": 3}
b = {"y": 20, "w": 40}

keys = a.keys()
a["new"] = 0
print(list(keys))
print(sorted(a.keys() & b.keys()), sorted(a.keys() - b.keys()))
Output
['x', 'y', 'z', 'new']
['y'] ['new', 'x', 'z']

Try it yourself

Try it yourself
Console output