Python Nested Dictionaries
Table of Contents
In the last lesson, we learned about Python Dictionary Methods. Now letβs organize more detailed data using dictionaries inside dictionaries.
Letβs Talk About Dictionaries Inside Dictionaries
We know what a dictionary is. It stores key-value pairs.
person = { "name": "Alex", "age": 25}But what if we want to store more complex information? Like a person who has a name, age, and also an address. And the address has a street, city, and zip code.
We could flatten it all into one dictionary.
person = { "name": "Alex", "age": 25, "street": "123 Main St", "city": "London", "zip": "SW1A 1AA"}That works. But it gets messy. The address details are mixed in with the person details.
A better way is to use a nested dictionary. That is a dictionary inside another dictionary.
person = { "name": "Alex", "age": 25, "address": { "street": "123 Main St", "city": "London", "zip": "SW1A 1AA" }}Now the address is its own dictionary. It is stored under the key "address". That keeps things organized.
How to Access Nested Values in Python
To access a value in a nested dictionary, we use multiple keys.
print(person["address"]["city"])Output
LondonFirst, person["address"] gives us the inner dictionary. Then ["city"] gives us the value.
We can go as deep as we want. If we had an inner dictionary inside another inner dictionary, we would just add more keys.
data = { "user": { "profile": { "name": "Alex" } }}print(data["user"]["profile"]["name"])Output
AlexAdding and Changing Nested Values in Python
We can add new keys to a nested dictionary the same way.
person["address"]["country"] = "UK"print(person["address"])Output
{'street': '123 Main St', 'city': 'London', 'zip': 'SW1A 1AA', 'country': 'UK'}We can also change existing values.
person["address"]["city"] = "Manchester"print(person["address"]["city"])Output
ManchesterLooping Through a Nested Dictionary in Python
We can loop through the outer dictionary. And for each inner dictionary, we can loop again.
person = { "name": "Alex", "age": 25, "address": { "street": "123 Main St", "city": "London", "zip": "SW1A 1AA" }}
for key, value in person.items(): if isinstance(value, dict): print(f"{key}:") for inner_key, inner_value in value.items(): print(f" {inner_key}: {inner_value}") else: print(f"{key}: {value}")Output
name: Alexage: 25address: street: 123 Main St city: London zip: SW1A 1AAThe isinstance(value, dict) checks if the value is a dictionary. If it is, we loop through it. Otherwise, we just print the value.
Python Nested Dictionaries: A Real-Life Example
Letβs store information about multiple people. Each person has their own dictionary.
people = { "alex": { "name": "Alex", "age": 25, "city": "London" }, "sam": { "name": "Sam", "age": 30, "city": "Manchester" }, "john": { "name": "John", "age": 22, "city": "Birmingham" }}
for username, info in people.items(): print(f"Username: {username}") print(f" Name: {info['name']}") print(f" Age: {info['age']}") print(f" City: {info['city']}") print()Output
Username: alex Name: Alex Age: 25 City: London
Username: sam Name: Sam Age: 30 City: Manchester
Username: john Name: John Age: 22 City: BirminghamThat is a very common way to store records. Like a database.
Another Example β A Game Inventory
inventory = { "weapons": { "sword": 1, "bow": 2, "arrow": 50 }, "potions": { "health": 5, "mana": 3 }, "gold": 100}
print(inventory["weapons"]["sword"])print(inventory["potions"]["health"])print(inventory["gold"])Output
15100That keeps different categories of items separate.
Common Mistakes with Python Nested Dictionaries
Mistake 1: Forgetting a Level of Keys
person = { "name": "Alex", "address": {"city": "London"}}print(person["city"]) # Error!So what do we do? We use the full path.
print(person["address"]["city"])Mistake 2: Using the Wrong Key
print(person["address"]["country"]) # Error if country doesn't existSo what do we do? We check if the key exists first, or use get().
print(person["address"].get("country", "Unknown"))Mistake 3: Trying to Modify a Nested Value Directly Without the Inner Key
person["address"] = "London" # This replaces the whole address dictionary with a stringLetβs be careful. We are replacing the entire inner dictionary. If we only want to change the city, we use the full path.
person["address"]["city"] = "London"Mistake 4: Thinking Nested Dictionaries Are Copied When We Copy the Outer Dictionary
import copy
original = {"a": {"b": 1}}shallow = original.copy()shallow["a"]["b"] = 2print(original)Output
{'a': {'b': 2}}Because the inner dictionary is shared. We use copy.deepcopy() if we need a truly independent copy.
Next, we will learn about Python Dictionary Comprehensions and build dictionaries with concise expressions.