Python Dictionary Methods
1Dictionary Methods: overview
Dictionary methods are the built-in tools for everyday dictionary jobs: reading with a fallback, creating entries on first use, removing and merging pairs, viewing keys and values, and building new dictionaries.
Before this lesson: Python Dictionaries
2Dictionary Methods: diagram
3Dictionary Methods: explained step by step
The dictionary lesson covered the basics: creating, reading with [], a first look at get(), and looping with items(). This lesson is about the methods you reach for when real data gets untidy: keys that may be missing, entries you must create on first use, pairs to remove, dictionaries to merge, and new dictionaries to build from other data.
get(): read without crashing
d.get(key, default) returns the value if the key exists and the default if it does not. It never adds the key to the dictionary. The default is used only when the key is absent: a key whose value is None or 0 is present, so you get that value back. To test for a key, use in, which looks at the keys, not the values.
stock = {"apples": 12, "pears": 0, "plums": None}
print(stock.get("pears", 5), stock.get("figs", 5), stock.get("plums", 5))
print("plums" in stock, 12 in stock.values(), 12 in stock)setdefault(): read, and create the entry if it is missing
d.setdefault(key, default) returns the value for key. If the key is missing, it first stores the default and then returns it. That makes it ideal for grouping, where every key needs a fresh list the first time you meet it.
groups = {}
for student, team in [("Asha", "red"), ("Ben", "blue"), ("Cara", "red")]:
groups.setdefault(team, []).append(student)
print(groups)The difference from get() matters: setdefault keeps the default, get forgets it. That is why groups.get(team, []).append(student) looks right but does nothing useful. It appends to a throwaway list.
Removing: pop, popitem, del and clear
Four tools remove entries, and they differ in what they give back and in how they treat a missing key.
cart = {"pen": 2, "ink": 1, "pad": 3, "cup": 4}
print(cart.pop("ink"))
print(cart.pop("glue", 0))
print(cart.popitem())
del cart["pen"]
print(cart)
cart.clear()
print(cart)pop(key) removes the key and returns its value; give it a second argument and a missing key returns that instead of raising KeyError. popitem() removes the most recently added pair and returns it as a tuple (and raises KeyError on an empty dictionary). del d[key] removes without returning anything and raises KeyError if the key is missing. clear() empties the dictionary.
Merging: |, |= and update()
a | b builds a new dictionary from both; when a key appears on both sides, the value from the right-hand side wins. a |= b and a.update(b) change a itself. update() also accepts keyword arguments when the keys are simple names.
defaults = {"theme": "light", "font": 14, "autosave": True}
prefs = {"theme": "dark", "font": 16}
merged = defaults | prefs
print(merged)
defaults.update(prefs)
print(defaults == merged)
defaults |= {"lang": "en"}
defaults.update(font=18, autosave=False)
print(defaults)There is no + for dictionaries. Like list methods, update() returns None, so never write settings = settings.update(...).
copy(): an independent top level
b = a gives the dictionary a second name, not a second dictionary. a.copy() creates a new one, so changing one no longer affects the other. It is a shallow copy: nested lists or dictionaries inside are still shared (see the lesson on copying).
base = {"a": 1}
alias = base
clone = base.copy()
alias["a"] = 99
print(base, clone)Live views: keys(), values() and items()
These methods return views, windows onto the dictionary rather than copies. If the dictionary changes later, an existing view shows the change. Key views also support set operations such as & and -.
prices = {"tea": 3, "cake": 4}
names = prices.keys()
prices["milk"] = 2
print(list(names))
print(sorted(prices.keys() & {"tea", "milk", "juice"}))
for name in list(prices):
if prices[name] < 3:
del prices[name]
print(prices)You may not add or remove keys while looping over a view; Python raises RuntimeError. Looping over list(prices) (a snapshot) makes the deletion safe.
Building dictionaries
dict.fromkeys(keys, value) gives every key the same starting value. dict(zip(keys, values)) pairs two lists, and dict() also accepts a list of (key, value) pairs. A dict comprehension filters or inverts an existing dictionary:
slots = dict.fromkeys(["mon", "tue", "wed"], 0)
names = ["Asha", "Ben", "Cara"]
marks = [82, 91, 77]
scores = dict(zip(names, marks))
print(slots)
print(scores)
passed = {n: s for n, s in scores.items() if s >= 80}
by_score = {s: n for n, s in scores.items()}
print(passed)
print(by_score)Inverting only works cleanly when the values are unique and hashable: two names with the same score would collapse into one key.
Order and sorting
A dictionary remembers insertion order. Changing a value keeps the key's position; deleting a key and adding it again moves it to the end. To order a dictionary by value, sort its items and build a new dictionary.
ranks = {"Ben": 91, "Asha": 82, "Cara": 77}
ranks["Asha"] = 85
del ranks["Ben"]
ranks["Ben"] = 91
print(list(ranks))
print(dict(sorted(ranks.items(), key=lambda pair: pair[1], reverse=True)))Which tool for a missing key?
- The key must exist:
d[key]. AKeyErroris the right alarm. - It might be missing and you just need a value:
d.get(key, default). - It might be missing and you want to create it:
d.setdefault(key, default). - Remove it if it is there:
d.pop(key, None). - Only act when it exists:
if key in d:.
Quick reference: Dictionary Methods
- Python Dictionary Cheat Sheet: Methods and Examples — A Python dictionary maps unique keys to values: read with `d[key]` or `d.get(key, default)`, add with `d[key]…
- How to Merge Two Dictionaries in Python — Use `merged = a | b` (Python 3.9+) or `merged = {**a, **b}` to merge two dictionaries into a new one. If both…
- How to Loop Through a Dictionary in Python — Use `for key, value in my_dict.items():` to loop over keys and values together. Loop over `my_dict` (or `.key…
- Python Dictionary get() Method — `dict.get(key, default=None)` returns the value for `key` if it exists, otherwise `default` (which is `None` …
- Python Dictionary items() Method — `dict.items()` returns a live view of the dictionary's `(key, value)` pairs, most often used as `for key, val…
- Python Dictionary keys() Method — `dict.keys()` returns a live, read-only view of all the keys in a dictionary, in insertion order. Convert it …
- Python Dictionary values() Method — `dict.values()` returns a live view of all the values stored in a dictionary, in insertion order, ready to lo…
- Python Dictionary update() Method — `dict.update(other)` copies every key-value pair from `other` into the dictionary, overwriting keys that alre…
4Dictionary Methods: syntax
d.get(key, default) # read; never adds the key
d.setdefault(key, default) # read; stores default if key is missing
d.pop(key, default) # remove and return; default avoids KeyError
d.popitem() # remove the last-added (key, value) pair
del d[key] # remove; KeyError if missing
d.clear() # remove everything
new = a | b # merge into a new dict (right side wins)
a |= b a.update(b) # merge into a, in place
d.copy() # shallow copy
d.keys() d.values() d.items() # live views
key in d value in d.values()
dict.fromkeys(keys, value) # same starting value for every key
dict(zip(keys, values)) # build from two lists
{k: v for k, v in d.items() if v > 0} # filter or invert
5Dictionary Methods: run the example
Press Run (or Ctrl + Enter). The output (step 6) appears directly below the code. Change anything and run it again.
orders = [("Asha", "tea"), ("Ben", "cake"), ("Cara", "tea"), ("Dev", "juice")]
menu = {"tea": 3, "cake": 4}
by_item = {}
for customer, item in orders:
by_item.setdefault(item, []).append(customer)
print(by_item)
menu.update({"juice": 2, "cake": 5})
total = 0
for item, buyers in by_item.items():
total += menu.get(item, 0) * len(buyers)
print("Total:", total)
removed = menu.pop("cake", None)
print("Removed price:", removed, "| menu:", menu)Expected output{'tea': ['Asha', 'Cara'], 'cake': ['Ben'], 'juice': ['Dev']}
Total: 13
Removed price: 5 | menu: {'tea': 3, 'juice': 2}
7Dictionary Methods: how the example works
Hover or tap a step to highlight its lines in the example above.
- Line 1-2
ordersis a list of(customer, item)pairs.menumaps each item to its price, but it does not know aboutjuiceyet. - Line 4
by_itemstarts as an empty dictionary that will map each item to the list of people who ordered it. - Line 5-6For every order,
setdefault(item, [])returns the list stored underitem, creating an empty one the first time the item appears..append(customer)then adds the customer to that stored list. - Line 7The groups come out in the order the items first appeared: tea (Asha, Cara), cake (Ben), juice (Dev).
- Line 9
update()merges the pairs intomenu:juiceis added, andcakeis overwritten with its new price of 5. - Line 10-13The loop reads each item and its buyers from
by_item.items().menu.get(item, 0)is the price, or 0 if an item were missing from the menu, and it is multiplied by the number of buyers: 32 + 51 + 2*1 = 13, which line 13 prints. - Line 15
pop("cake", None)removes the cake entry and returns its price, 5. The defaultNonemeans a missing key would not raise an error. - Line 16The menu has lost
cakebut keptteaandjuice, in their original order.
8Dictionary Methods: common mistakes
Using get() when you meant setdefault()
✗ Wrong
groups = {}
for team, name in [("red", "Asha"), ("blue", "Ben"), ("red", "Cara")]:
groups.get(team, []).append(name)
print(groups)✓ Right
groups = {}
for team, name in [("red", "Asha"), ("blue", "Ben"), ("red", "Cara")]:
groups.setdefault(team, []).append(name)
print(groups)get() returns the default without storing it, so each name is appended to a throwaway list. setdefault() stores the new list in the dictionary and returns it.
dict.fromkeys() with a list as the value
✗ Wrong
week = dict.fromkeys(["mon", "tue"], [])
week["mon"].append("gym")
print(week)✓ Right
week = {day: [] for day in ["mon", "tue"]}
week["mon"].append("gym")
print(week)fromkeys() stores the very same object under every key. That is fine for numbers and strings, but a list or dictionary must be created separately for each key, which a dict comprehension does.
Deleting keys while looping over the dictionary
✗ Wrong
stock = {"pen": 0, "ink": 4, "pad": 0}
for name, qty in stock.items():
if qty == 0:
del stock[name]
print(stock)✓ Right
stock = {"pen": 0, "ink": 4, "pad": 0}
for name, qty in list(stock.items()):
if qty == 0:
del stock[name]
print(stock)You cannot add or remove keys while a loop is walking through the dictionary. Loop over a snapshot taken with list(...), or build a new dictionary with a comprehension.
Popping a key that is not there
✗ Wrong
cart = {"pen": 2}
removed = cart.pop("glue")
print(removed)✓ Right
cart = {"pen": 2}
removed = cart.pop("glue", None)
print(removed)pop(key) with no default raises KeyError for a missing key, just like d[key]. Pass a second argument to get that value back instead.
Testing for a value with in
✗ Wrong
stock = {"apples": 12, "pears": 0}
if 12 in stock:
print("Found 12")
else:
print("No 12 in stock")✓ Right
stock = {"apples": 12, "pears": 0}
if 12 in stock.values():
print("Found 12")
else:
print("No 12 in stock")On a dictionary, x in d asks whether x is a key. To look through the values, use x in d.values().
9Dictionary Methods: exercises
Write your answer, then press Check. The checks run in your browser.
1. Settings with defaults
Write code Easy ✓ CompletedComplete with_defaults(settings, defaults). It must return a new dictionary that contains every default, with the user's settings overriding any default that has the same key. Neither argument may be changed.
def with_defaults(settings, defaults):
# return a NEW dict: all defaults, overridden by settings
pass
print(with_defaults({"theme": "dark"}, {"theme": "light", "font": 14}))
def with_defaults(settings, defaults):
return defaults | settings
print(with_defaults({"theme": "dark"}, {"theme": "light", "font": 14}))
2. Predict the dictionary methods
Predict the output Easy ✓ CompletedRead the code and type exactly what it prints, line by line. Then press Check to run it and compare.
tally = {"a": 1}
print(tally.setdefault("a", 10))
print(tally.setdefault("b", 20))
print(tally.get("c", 30))
print(tally)
print(tally.pop("b"))
print(tally.popitem())
print(tally)
1
20
30
{'a': 1, 'b': 20}
20
('a', 1)
{}
2 more exercises → 6 more examples
Questions learners ask
How do I merge two dictionaries in Python?
Use a | b to create a new dictionary (Python 3.9 and later), or a |= b and a.update(b) to change a in place. {**a, **b} also works in older versions. When both dictionaries have the same key, the value from the right-hand side wins. Dictionaries do not support +.
What is the difference between pop(), popitem() and del on a dictionary?
pop(key) removes the key and returns its value, and pop(key, default) returns the default instead of raising KeyError. popitem() removes and returns the most recently added (key, value) pair. del d[key] removes the key and returns nothing, and raises KeyError if the key is missing.
When should I use setdefault() instead of get()?
Use get() when you only want to read a value and fall back to a default; it never changes the dictionary. Use setdefault() when the default should also be stored, such as creating an empty list the first time a key appears so you can append to it straight away.
Further reading
10Next lesson
Up nextPython Nested Data StructuresA nested data structure is a list, dict or tuple that contains other lists or dicts, and you reach a value deep inside …Related:
Python DictionariesPython Nested Data StructuresPython collections ModulePython KeyError: What It Means and How to Fix It
← Python Dictionaries · All Data Structures lessons · Practise in the IDE