What you'll learn
- Create a dictionary of key-value pairs and read a value by its key
- Add, change, and delete entries
- Look up a key that might be missing without crashing, using
inandget() - Loop over keys, values, and pairs with
items()
Concept
A list answers "what is at position 3?". A dictionary answers "what is the price of coffee?". It stores pairs: a key you look things up by, and the value stored under it. You write one with curly braces, {"coffee": 3.5, "bagel": 2.25}, and read a value with the key in square brackets, prices["coffee"]. Keys are usually strings or numbers, and each key appears once.

Adding and changing use the same syntax: prices["juice"] = 4.0 creates the entry if the key is new and overwrites it if the key exists. del prices["bagel"] removes an entry, and prices.pop("bagel") removes it and hands the value back. Since Python 3.7, dictionaries remember insertion order, so looping over one visits the entries in the order you added them.
Asking for a key that is not there raises a KeyError. Two tools avoid that. key in prices tells you whether the key exists. prices.get(key) returns the value if it exists and None otherwise, or a default you supply: prices.get("tea", 0). Reach for get when a missing key is normal and for square brackets when a missing key would be a bug you want to hear about.
| Expression | Key present | Key missing |
|---|---|---|
d[key] |
the value | KeyError |
d.get(key) |
the value | None |
d.get(key, default) |
the value | default |
key in d |
True |
False |
Looping over a dictionary gives you its keys. To get the values use .values(), and to get both at once use .items(), which yields pairs you can unpack straight into two loop variables: for name, price in prices.items():. That last form is the one you will write most.

Code
Create a dictionary, read from it, and change it. Adding and overwriting look identical; the key decides which happens.
# menu.py
prices = {"coffee": 3.5, "bagel": 2.25}
print(prices["coffee"])
prices["juice"] = 4.0
prices["coffee"] = 3.75
print(prices)
print(len(prices))
del prices["bagel"]
print(prices)
3.5
{'coffee': 3.75, 'bagel': 2.25, 'juice': 4.0}
3
{'coffee': 3.75, 'juice': 4.0}Looking up keys that may be missing. Square brackets raise, in checks first, get gives None or a default of your choosing.
# missing.py
prices = {"coffee": 3.5}
print("tea" in prices)
print(prices.get("tea"))
print(prices.get("tea", 0))
print(prices["tea"])
False
None
0
Traceback (most recent call last):
File "missing.py", line 6, in <module>
print(prices["tea"])
~~~~~~^^^^^^^
KeyError: 'tea'Looping three ways. items() with two loop variables is the form to remember.
# walk.py
prices = {"coffee": 3.5, "bagel": 2.25, "juice": 4.0}
for name in prices:
print(name, end=" ")
print()
total = 0
for price in prices.values():
total += price
print(f"total {total:.2f}")
for name, price in prices.items():
print(f"{name:<8}{price:>6.2f}")
coffee bagel juice
total 9.75
coffee 3.50
bagel 2.25
juice 4.00Counting with a dictionary is the accumulate pattern with a key. get(word, 0) makes the first sighting of a word start from zero.
# count_words.py
text = "the cat sat on the mat the end"
counts = {}
for word in text.split():
counts[word] = counts.get(word, 0) + 1
print(counts)
print("most common:", max(counts, key=counts.get))
{'the': 3, 'cat': 1, 'sat': 1, 'on': 1, 'mat': 1, 'end': 1}
most common: theTry it yourself
Create contacts.py with a dictionary mapping three names to phone numbers. Print one number by name, add a fourth contact, change one existing number, and delete one. Then loop with items() to print every contact as name: number. Finally, look up a name that is not there with get and print a friendly message instead of crashing.
Common mistakes
- Using a list where a dictionary belongs. If you find yourself searching a list for a name to get its value, you want a dictionary; the lookup is instant and the code says what it means.
- Reading with square brackets when the key might be missing. That is a
KeyErrorwaiting for the first unusual input; usegetor check within. - Looping over
d.items()but naming only one variable.for pair in d.items()gives you tuples; writefor key, value in d.items()to unpack them.
What's next
- A dictionary maps keys to values; read with
d[key], add or change withd[key] = value, remove withdel. inandget(key, default)handle keys that might be missing without aKeyError.- Loop with
.items()to get key and value together; dictionaries keep insertion order.
You have both core collections. Next you will meet the built-in functions that work on all of them, the ones you will type more than any others.