Dictionaries Advanced
Master advanced dictionary techniques like nesting, merging, and comprehensions
Dictionaries Advanced
Updating Multiple Items
Sometimes you want to add or change several items at once. The update() method makes this easy.
student = {"name": "John", "age": 20}
new_info = {"grade": "A", "email": "john@example.com"}
student.update(new_info)
print(student)What happens: Both "grade" and "email" get added to the student dictionary. If any keys already existed, their values would be updated.
You can also write it like this:
student.update(grade="A", email="john@example.com")
print(student)Same result, different syntax.
Copying Dictionaries
When you need a copy of a dictionary, be careful how you do it.
Wrong Way - This Doesn't Copy
student1 = {"name": "John", "age": 20}
student2 = student1
student2["age"] = 25
print(student1)Surprise: Both student1 and student2 show age as 25. They point to the same dictionary.
Right Way - Use copy()
student1 = {"name": "John", "age": 20}
student2 = student1.copy()
student2["age"] = 25
print(student1)
print(student2)What happens:
- student1 keeps age as 20
- student2 has age as 25
- They are separate dictionaries now
Nested Dictionaries
A nested dictionary means having dictionaries inside dictionaries. This is useful for organizing complex data.
school = {
"student1": {"name": "John", "age": 20, "grade": "A"},
"student2": {"name": "Sarah", "age": 22, "grade": "B"}
}What this structure means: The school dictionary contains two students. Each student is itself a dictionary with their own information.
Accessing Nested Data
print(school["student1"]["name"])
print(school["student2"]["age"])What this shows:
- First line gets John (student1's name)
- Second line gets 22 (student2's age)
Think of it like folders: school → student1 → name → "John"
Modifying Nested Data
school["student1"]["grade"] = "A+"
print(school["student1"])Result: Changes John's grade from "A" to "A+".
Dictionary from Two Lists
You can combine two lists into a dictionary using zip().
keys = ["name", "age", "grade"]
values = ["John", 20, "A"]
student = dict(zip(keys, values))
print(student)What happens:
- zip() pairs up items from both lists
- dict() converts these pairs into a dictionary
- Result: {"name": "John", "age": 20, "grade": "A"}
Real-world use: When you have column names and a row of data, this creates a structured record.
Dictionary Comprehension
Dictionary comprehension is a short way to create dictionaries using a loop in one line.
Basic Pattern
numbers = [1, 2, 3, 4]
squares = {x: x * x for x in numbers}
print(squares)Result: {1: 1, 2: 4, 3: 9, 4: 16}
How it works: For each number x, create a key-value pair where key is x and value is x times x.
With Condition
numbers = [1, 2, 3, 4, 5]
even_squares = {x: x * x for x in numbers if x % 2 == 0}
print(even_squares)Result: {2: 4, 4: 16}
What this does: Only creates entries for even numbers.
Converting Existing Dictionary
prices = {"apple": 1.5, "banana": 0.8, "orange": 2.0}
expensive = {item: price for item, price in prices.items() if price > 1}
print(expensive)Result: {"apple": 1.5, "orange": 2.0}
What happens: Creates new dictionary with only items where price is more than 1.
Default Values with setdefault()
The setdefault() method gets a value if key exists, or sets a default value if it doesn't.
student = {"name": "John", "age": 20}
grade = student.setdefault("grade", "Not assigned")
email = student.setdefault("email", "No email")
print(student)What happens:
- "grade" doesn't exist, so it adds "grade": "Not assigned"
- "email" doesn't exist, so it adds "email": "No email"
- Both are now in the dictionary
Difference from get():
- get() just returns a default, doesn't add it
- setdefault() adds the default to dictionary
Merging Dictionaries
In Python 3.9+, you can merge dictionaries using the pipe operator.
dict1 = {"name": "John", "age": 20}
dict2 = {"grade": "A", "email": "john@example.com"}
combined = dict1 | dict2
print(combined)Result: {"name": "John", "age": 20, "grade": "A", "email": "john@example.com"}
If keys overlap:
dict1 = {"name": "John", "age": 20}
dict2 = {"age": 25, "grade": "A"}
combined = dict1 | dict2
print(combined)Result: {"name": "John", "age": 25, "grade": "A"}
The second dictionary's values win when keys match.
Sorting Dictionaries
Dictionaries remember insertion order, but you can create sorted versions.
Sort by Keys
data = {"c": 3, "a": 1, "b": 2}
sorted_dict = dict(sorted(data.items()))
print(sorted_dict)Result: {"a": 1, "b": 2, "c": 3}
Sort by Values
scores = {"John": 85, "Sarah": 92, "Mike": 78}
sorted_scores = dict(sorted(scores.items(), key=lambda x: x[1]))
print(sorted_scores)Result: {"Mike": 78, "John": 85, "Sarah": 92}
What this means: Sorts by score (value) instead of name (key).
Practice Example
The scenario: You're managing an inventory system with nested product data and need to perform various operations.
inventory = {
"laptop": {"price": 999, "stock": 5, "category": "Electronics"},
"phone": {"price": 599, "stock": 10, "category": "Electronics"},
"desk": {"price": 299, "stock": 3, "category": "Furniture"}
}
print("Laptop price:", inventory["laptop"]["price"])
inventory["laptop"]["stock"] = inventory["laptop"]["stock"] - 1
print("Laptop stock after sale:", inventory["laptop"]["stock"])
new_product = {"monitor": {"price": 399, "stock": 7, "category": "Electronics"}}
inventory.update(new_product)
expensive = {name: info for name, info in inventory.items() if info["price"] > 500}
print("Expensive products:", expensive.keys())
electronics = {name: info for name, info in inventory.items() if info["category"] == "Electronics"}
print("Electronics count:", len(electronics))
product_names = list(inventory.keys())
print("All products:", product_names)What this program does:
- Creates nested inventory with 3 products
- Accesses laptop price (nested value)
- Reduces laptop stock after a sale
- Adds new monitor product
- Filters products over 500 dollars using comprehension
- Filters only electronics category
- Gets list of all product names
Key Points to Remember
update() adds multiple key-value pairs at once. If keys exist, values get updated. If not, new pairs are added.
Use copy() to make a real duplicate. Simple assignment creates a reference, not a copy.
Nested dictionaries store dictionaries inside dictionaries. Access using multiple brackets: dict[key1][key2].
Dictionary comprehension creates dictionaries in one line using pattern: {key: value for item in sequence}.
setdefault() gets a value if key exists, or adds and returns a default if it doesn't. Different from get() which just returns without adding.
Common Mistakes
Mistake 1: Shallow copy with nested dictionaries
data1 = {"user": {"name": "John"}}
data2 = data1.copy()
data2["user"]["name"] = "Sarah" # Changes both!For nested dictionaries, use:
import copy
data2 = copy.deepcopy(data1)Mistake 2: Wrong comprehension syntax
squares = {x * x for x in [1, 2, 3]} # This creates a set, not dict
squares = {x: x * x for x in [1, 2, 3]} # Correct! Need colonMistake 3: Forgetting nested dictionary exists
data = {"user": {"name": "John"}}
data["user"] = "Sarah" # This replaces entire nested dict!
data["user"]["name"] = "Sarah" # Correct! Updates nested valueWhat's Next?
You now know advanced dictionary techniques. Next, you'll learn about sets - a unique data structure that stores only unique values and provides powerful operations for comparing groups of data.