February 11, 2026 · All About CS
Python Dictionaries: All 11 Built-in Methods (Part 3 of 3)
A complete reference for every Python dictionary method — .clear(), .copy(), .fromkeys(), .get(), .items(), .keys(), .values(), .pop(), .popitem(), .setdefault(), and .update() — with practical examples.
Python Dictionaries: All 11 Built-in Methods
Python dictionaries come with 11 built-in methods that cover everything from safe access to bulk updates to shallow copying. In Parts 1 and 2, we covered the fundamentals and daily operations. This final part is your complete method reference — each method explained with its signature, behavior, and practical examples.
Quick Reference Table
| Method | Description | Returns |
|---|---|---|
.clear() | Remove all entries | None |
.copy() | Shallow copy | New dict |
.fromkeys() | Create dict from key sequence | New dict |
.get() | Safe access with default | Value or default |
.items() | Key-value pairs | View object |
.keys() | All keys | View object |
.values() | All values | View object |
.pop() | Remove by key, return value | Removed value |
.popitem() | Remove last inserted pair | (key, value) tuple |
.setdefault() | Get or insert with default | Value |
.update() | Merge another dict/iterable | None |
1. .clear() — Remove All Entries
Signature: dict.clear()
Removes every key-value pair from the dictionary, leaving it empty. This modifies the dictionary in place and returns None.
data = {"a": 1, "b": 2, "c": 3}
data.clear()
print(data) # {}.clear() vs. Reassignment
There is an important difference between .clear() and assigning a new empty dict:
original = {"x": 10, "y": 20}
alias = original
# .clear() affects all references
original.clear()
print(alias) # {} — alias sees the change
# Reassignment only rebinds the variable
original = {"x": 10, "y": 20}
alias = original
original = {}
print(alias) # {'x': 10, 'y': 20} — alias still points to old dictUse .clear() when other variables reference the same dictionary and you want them all to see the empty result. Use reassignment when you want a fresh start without affecting other references.
2. .copy() — Shallow Copy
Signature: dict.copy()
Returns a shallow copy of the dictionary — a new dict object with the same key-value pairs. Changes to the copy do not affect the original (for top-level values).
original = {"x": 10, "y": 20}
clone = original.copy()
clone["x"] = 99
print(original["x"]) # 10 — original is unaffected
print(clone["x"]) # 99Shallow vs. Deep Copy
The copy is shallow, meaning nested mutable objects are shared between the original and the copy:
data = {"scores": [90, 85, 78], "name": "Test"}
backup = data.copy()
backup["scores"].append(95)
print(data["scores"]) # [90, 85, 78, 95] — the list is shared!
print(backup["scores"]) # [90, 85, 78, 95]For truly independent copies of nested structures, use copy.deepcopy():
import copy
data = {"scores": [90, 85, 78], "name": "Test"}
backup = copy.deepcopy(data)
backup["scores"].append(95)
print(data["scores"]) # [90, 85, 78] — original is safe
print(backup["scores"]) # [90, 85, 78, 95]3. .fromkeys(keys, value) — Create from Key Sequence
Signature: dict.fromkeys(iterable, value=None)
Creates a new dictionary with keys from the given iterable, all set to the same value. This is a class method — you call it on dict itself, not on an instance.
subjects = ["math", "science", "english"]
scores = dict.fromkeys(subjects, 0)
print(scores) # {'math': 0, 'science': 0, 'english': 0}If you omit the value, all keys map to None:
fields = dict.fromkeys(["name", "age", "email"])
print(fields) # {'name': None, 'age': None, 'email': None}Gotcha with mutable defaults: If the value is a mutable object like a list, all keys share the same list object. Use a dictionary comprehension instead if you need independent mutable values.
# Dangerous — all keys share the same list
shared = dict.fromkeys(["a", "b", "c"], [])
shared["a"].append(1)
print(shared) # {'a': [1], 'b': [1], 'c': [1]} — all affected!
# Safe — each key gets its own list
independent = {key: [] for key in ["a", "b", "c"]}
independent["a"].append(1)
print(independent) # {'a': [1], 'b': [], 'c': []}4. .get(key, default) — Safe Access
Signature: dict.get(key, default=None)
Returns the value for the given key if it exists. If the key is missing, returns the default value instead of raising KeyError. This is the safest way to retrieve dictionary values.
settings = {"theme": "dark", "language": "en"}
print(settings.get("theme")) # 'dark'
print(settings.get("font_size", 14)) # 14 — key missing, default returned
print(settings.get("font_size")) # None — default is None when omitted.get() vs. Square Brackets
# Square brackets — raises KeyError on missing key
try:
value = settings["font_size"]
except KeyError:
value = 14
# .get() — cleaner, no exception handling needed
value = settings.get("font_size", 14)Practical Use: Counting Pattern
text = "banana"
freq = {}
for char in text:
freq[char] = freq.get(char, 0) + 1
print(freq) # {'b': 1, 'a': 3, 'n': 2}Practical Use: Safe Nested Access
response = {"data": {"user": {"name": "Priya"}}}
name = response.get("data", {}).get("user", {}).get("name", "Unknown")
print(name) # 'Priya'
missing = response.get("data", {}).get("profile", {}).get("bio", "N/A")
print(missing) # 'N/A'5. .items() — Key-Value Pairs as View
Signature: dict.items()
Returns a view object containing (key, value) tuples. This is the go-to method for iterating over both keys and values simultaneously.
menu = {"coffee": 4.50, "tea": 3.00, "juice": 5.25}
for item, price in menu.items():
print(f"{item}: ${price:.2f}")
# coffee: $4.50
# tea: $3.00
# juice: $5.25Converting to a List of Tuples
pairs = list(menu.items())
print(pairs) # [('coffee', 4.5), ('tea', 3.0), ('juice', 5.25)]View Objects Are Dynamic
items_view = menu.items()
print(len(items_view)) # 3
menu["smoothie"] = 6.00
print(len(items_view)) # 4 — the view reflects the change6. .keys() — All Keys as View
Signature: dict.keys()
Returns a view object of all keys in the dictionary.
menu = {"coffee": 4.50, "tea": 3.00, "juice": 5.25}
print(list(menu.keys())) # ['coffee', 'tea', 'juice']Set Operations on Key Views
Key views support set-like operations, which is useful for comparing dictionaries:
dict_a = {"x": 1, "y": 2, "z": 3}
dict_b = {"y": 20, "z": 30, "w": 40}
# Keys in both
print(dict_a.keys() & dict_b.keys()) # {'y', 'z'}
# Keys in a but not b
print(dict_a.keys() - dict_b.keys()) # {'x'}
# All keys from both
print(dict_a.keys() | dict_b.keys()) # {'x', 'y', 'z', 'w'}7. .values() — All Values as View
Signature: dict.values()
Returns a view object of all values in the dictionary.
menu = {"coffee": 4.50, "tea": 3.00, "juice": 5.25}
print(list(menu.values())) # [4.5, 3.0, 5.25]
# Useful for aggregation
total = sum(menu.values())
print(f"Total: ${total:.2f}") # Total: $12.75
average = total / len(menu)
print(f"Average: ${average:.2f}") # Average: $4.25Unlike .keys(), the .values() view does not support set operations because values are not guaranteed to be hashable or unique.
8. .pop(key, default) — Remove and Return
Signature: dict.pop(key, default=<not given>)
Removes the specified key and returns its value. If the key is not found and a default is provided, returns the default. If no default is given and the key is missing, raises KeyError.
inventory = {"apples": 5, "bananas": 3, "cherries": 12}
removed = inventory.pop("bananas")
print(removed) # 3
print(inventory) # {'apples': 5, 'cherries': 12}With a Default Value
missing = inventory.pop("grapes", 0)
print(missing) # 0 — no KeyError
print(inventory) # {'apples': 5, 'cherries': 12}Without a Default (Key Missing)
# inventory.pop("grapes") # KeyError: 'grapes'Practical Use: Processing and Removing
task_queue = {"task_1": "send email", "task_2": "generate report", "task_3": "backup db"}
while task_queue:
task_id, action = task_queue.popitem()
print(f"Processing {task_id}: {action}")9. .popitem() — Remove Last Inserted Pair
Signature: dict.popitem()
Removes and returns the last inserted key-value pair as a tuple. Raises KeyError if the dictionary is empty. Since Python 3.7, "last" means the most recently inserted item (LIFO order).
tasks = {"morning": "exercise", "afternoon": "code", "evening": "read"}
last = tasks.popitem()
print(last) # ('evening', 'read')
print(tasks) # {'morning': 'exercise', 'afternoon': 'code'}
second = tasks.popitem()
print(second) # ('afternoon', 'code')
print(tasks) # {'morning': 'exercise'}Empty Dictionary
empty = {}
# empty.popitem() # KeyError: 'popitem(): dictionary is empty'.popitem() is useful for implementing stack-like (LIFO) behavior with dictionaries, or for draining a dictionary item by item.
10. .setdefault(key, default) — Get or Insert
Signature: dict.setdefault(key, default=None)
If the key exists, returns its value without modification. If the key is missing, inserts the key with the given default value and returns that value. This is an atomic "get-or-create" operation.
preferences = {"theme": "dark"}
# Key exists — returns existing value, no modification
theme = preferences.setdefault("theme", "light")
print(theme) # 'dark'
print(preferences) # {'theme': 'dark'}
# Key missing — inserts default and returns it
font = preferences.setdefault("font_size", 16)
print(font) # 16
print(preferences) # {'theme': 'dark', 'font_size': 16}Practical Use: Grouping Items
.setdefault() shines when building dictionaries of lists:
students = [
("CS", "Alice"), ("Math", "Bob"), ("CS", "Carol"),
("Math", "Dan"), ("CS", "Eve"), ("Physics", "Frank")
]
by_department = {}
for dept, name in students:
by_department.setdefault(dept, []).append(name)
print(by_department)
# {'CS': ['Alice', 'Carol', 'Eve'], 'Math': ['Bob', 'Dan'], 'Physics': ['Frank']}Without .setdefault(), you would need an if check or collections.defaultdict. This method keeps the code concise.
11. .update(other) — Merge Another Dict
Signature: dict.update(other=(), **kwargs)
Merges key-value pairs from another dictionary or iterable into the current dictionary. Existing keys are overwritten by the incoming values. Modifies in place and returns None.
defaults = {"color": "blue", "size": "medium", "quantity": 1}
overrides = {"size": "large", "gift_wrap": True}
defaults.update(overrides)
print(defaults)
# {'color': 'blue', 'size': 'large', 'quantity': 1, 'gift_wrap': True}From Keyword Arguments
config = {"host": "localhost"}
config.update(port=5432, debug=True)
print(config) # {'host': 'localhost', 'port': 5432, 'debug': True}From an Iterable of Pairs
config = {"host": "localhost"}
config.update([("port", 5432), ("debug", True)])
print(config) # {'host': 'localhost', 'port': 5432, 'debug': True}Practical Use: Merging Configuration Layers
A common pattern is layering defaults with environment-specific overrides:
defaults = {"db_host": "localhost", "db_port": 5432, "debug": False, "log_level": "INFO"}
production = {"db_host": "prod-db.example.com", "debug": False, "log_level": "WARNING"}
development = {"debug": True, "log_level": "DEBUG"}
# Build final config by layering
config = {}
config.update(defaults)
config.update(production) # or development, depending on environment
print(config)
# {'db_host': 'prod-db.example.com', 'db_port': 5432, 'debug': False, 'log_level': 'WARNING'}Method Cheat Sheet
Here is a quick decision guide for choosing the right method:
| I want to… | Use |
|---|---|
| Get a value safely (no crash) | .get(key, default) |
| Check if a key exists | key in dict |
| Remove a specific key and get its value | .pop(key, default) |
| Remove the last inserted entry | .popitem() |
| Get or insert a default value | .setdefault(key, default) |
| Merge two dictionaries | .update(other) or dict1 | dict2 |
| Get all keys, values, or pairs | .keys(), .values(), .items() |
| Empty the dictionary | .clear() |
| Make a copy | .copy() (shallow) or copy.deepcopy() |
| Create from key list with same value | dict.fromkeys(keys, value) |
What We Covered in This Series
Across all three parts, you now have a complete understanding of Python dictionaries:
- Part 1 — Basics: What dictionaries are, how to create them, key restrictions (hashable types), accessing values, case sensitivity, and integer keys.
- Part 2 — Operations: Adding/updating entries, iterating by keys, values, and items, nested dictionaries, dictionary comprehensions, and membership testing with
in. - Part 3 — Methods: All 11 built-in methods with signatures, behaviors, gotchas, and practical patterns.
Dictionaries are at the heart of almost every Python program — from configuration files to API responses to database records. Master these methods and patterns, and you will handle any key-value challenge with confidence.