When you start working with real-world data in Python, a simple flat dictionary quickly runs out of room. That is where the python nested dictionary steps in. A python nested dictionary is a dictionary where one or more values are themselves dictionaries, letting you represent layered, hierarchical data — like student records, config files, or JSON API responses — in a clean and readable way. In this guide you will learn how to create, access, update, delete, iterate, and write comprehensions for nested dictionaries, with clear examples at every step.

What Is a Python Nested Dictionary?

A python nested dictionary is a dictionary that contains one or more other dictionaries as values. Think of it like a filing cabinet: the outer dictionary is the cabinet, and each drawer holds another dictionary with its own set of keys and values.

Here is the simplest way to picture it:

student = {
 "name": "Alice",
 "grades": {
 "math": 92,
 "science": 88,
 "english": 95
 }
}

In this example, "grades" is a key whose value is another dictionary. That inner dictionary holds subject names as keys and scores as values. This is the core idea behind a dictionary inside dictionary in Python — layers of key-value pairs nested inside each other. Python's official dictionary documentation confirms that dictionary values can be any Python object, including other dictionaries, which is exactly what makes this structure so flexible.

Creating a Nested Dictionary in Python

There are a few natural ways to create a nested dictionary. The most direct approach is to write it as a literal when you define the variable. But you can also build one step by step, which is useful when you are constructing it dynamically from user input or an API.

Building a nested dict from scratch:

inventory = {}

inventory["fruits"] = {}
inventory["fruits"]["apple"] = 50
inventory["fruits"]["mango"] = 30

inventory["vegetables"] = {}
inventory["vegetables"]["carrot"] = 80
inventory["vegetables"]["spinach"] = 45

print(inventory)

Output:

{'fruits': {'apple': 50, 'mango': 30}, 'vegetables': {'carrot': 80, 'spinach': 45}}

First you create an empty outer dictionary. Then you add a key "fruits" and assign an empty dictionary to it. After that you fill the inner dictionary with item names and quantities. You repeat the same process for "vegetables". This approach is exactly how you would python create nested dictionary entries when data arrives one piece at a time.

Using the dict() constructor:

Python's built-in dict() function also works cleanly for this:

employee = dict(
 name="Jordan",
 department="Engineering",
 contact=dict(
 email="[email protected]",
 phone="555-1234"
 )
)

print(employee)

Output:

{'name': 'Jordan', 'department': 'Engineering', 'contact': {'email': '[email protected]', 'phone': '555-1234'}}

The contact key holds another dict() call, making this a neat and expressive way to express a python multilevel dictionary. Both approaches produce the same result — choose whichever fits the situation better.

Accessing Values in a Nested Dict

Reading values from a python nested dictionary uses chained square bracket notation — one set of brackets for each level you want to go into. The more levels your data has, the more brackets you chain.

school = {
 "class_a": {
 "teacher": "Ms. Rivera",
 "students": 28,
 "scores": {
 "avg_math": 84,
 "avg_english": 79
 }
 },
 "class_b": {
 "teacher": "Mr. Chen",
 "students": 31,
 "scores": {
 "avg_math": 91,
 "avg_english": 87
 }
 }
}

print(school["class_a"]["teacher"])
print(school["class_b"]["scores"]["avg_math"])

Output:

Ms. Rivera
91

The first print goes two levels deep — outer key "class_a" then inner key "teacher". The second goes three levels deep: "class_b""scores""avg_math". Each bracket pair peels back one layer. This is the standard python nested dict access pattern and it scales to as many levels as your data structure needs.

The one risk here is that if any key in the chain does not exist, Python raises a KeyError. The next section shows you how to handle that safely.

Safely Reading a Nested Dict with .get()

The .get() method returns None — or a default you specify — instead of throwing an error when a key is missing. With a python nested dictionary, you chain .get() calls to navigate through levels without risk.

config = {
 "database": {
 "host": "localhost",
 "port": 5432
 }
}

host = config.get("database", {}).get("host", "unknown")
timeout = config.get("database", {}).get("timeout", 30)
cache = config.get("cache", {}).get("host", "not configured")

print(host)
print(timeout)
print(cache)

Output:

localhost
30
not configured

timeout does not exist in the "database" dict, so .get() returns the default 30. "cache" does not exist in the outer dict at all, so the first .get() returns {} (an empty dict), and the second .get() safely falls back to "not configured". This chained .get() pattern is one of the most practical tools you have when working with a nested dictionary python scenario where keys may or may not be present — especially with data from external APIs or config files.

Adding and Updating a Nested Dict in Python

To add a new entry or update an existing value in a python nested dictionary, you use the same bracket notation as access — just assign to it rather than reading from it.

Adding a new key and updating an existing one:

library = {
 "fiction": {
 "author": "Elena Marsh",
 "count": 142
 }
}

library["nonfiction"] = {
 "author": "David Okafor",
 "count": 98
}

library["fiction"]["count"] = 155

print(library)

Output:

{'fiction': {'author': 'Elena Marsh', 'count': 155}, 'nonfiction': {'author': 'David Okafor', 'count': 98}}

The first line adds a completely new top-level key "nonfiction" with its own inner dictionary. The second line uses python update nested dict style to change the "count" inside "fiction" from 142 to 155. Python handles both in the same intuitive way — navigate to the target key and assign.

Applying multiple updates at once with .update():

profile = {
 "user": "Maya",
 "settings": {
 "theme": "dark",
 "notifications": True
 }
}

profile["settings"].update({
 "notifications": False,
 "language": "en-US"
})

print(profile["settings"])

Output:

{'theme': 'dark', 'notifications': False, 'language': 'en-US'}

Calling .update() on the inner dictionary merges the new pairs into it. "notifications" is overwritten and "language" is added as a brand new key — all in one line. This is a cleaner approach when you need to apply several changes to a nested level at once.

Python's .update() method works on any dictionary object, which means you can call it on any level of your python multilevel dictionary structure.

Deleting Keys from a Multilevel Dictionary

Removing entries from a python nested dictionary uses the del keyword — the same as with any regular Python dict.

catalog = {
 "electronics": {
 "laptop": 1200,
 "tablet": 450,
 "headphones": 85
 },
 "clothing": {
 "jacket": 200,
 "shoes": 130
 }
}

del catalog["electronics"]["tablet"]
del catalog["clothing"]

print(catalog)

Output:

{'electronics': {'laptop': 1200, 'headphones': 85}}

The first del removes only the "tablet" key from inside "electronics", leaving the rest of that inner dict intact. The second del removes the entire "clothing" key — including its inner dictionary — from the outer dict. Always make sure a key exists before deleting it, or you will get a KeyError.

If you want to remove a key and capture its value at the same time, use .pop():

removed_price = catalog["electronics"].pop("headphones", None)
print(removed_price)
print(catalog)

Output:

85
{'electronics': {'laptop': 1200}}

.pop() removes "headphones" and returns its value 85. If the key had not existed, None would have been returned instead of an error.

Iterating Over a Nested Dictionary in Python

To process every entry in a python nested dictionary, you iterate through it using Python's .items() method, which gives you key-value pairs at each level. For a nested structure, you use nested for loops.

scores = {
 "Alice": {"math": 90, "science": 85},
 "Bob": {"math": 78, "science": 92},
 "Clara": {"math": 95, "science": 88}
}

for student, subjects in scores.items():
 print(f"Student: {student}")
 for subject, score in subjects.items():
 print(f" {subject}: {score}")
 print()

Output:

Student: Alice
 math: 90
 science: 85

Student: Bob
 math: 78
 science: 92

Student: Clara
 math: 95
 science: 88

The outer loop iterates through students, and the inner loop iterates through each student's subjects. This nested for loop pattern is the standard way to python iterate nested dictionary data. You go one level deeper for each nested layer in your structure. Python's built-in .items() works on any dictionary object — call it at whichever depth you need.

Nested Dict Comprehension in Python

A python nested dict comprehension builds a nested dictionary using a concise expression — the same idea as a list comprehension, but producing a dict at every level.

Here is an example that generates a multiplication table as a nested dictionary:

tables = {
 outer: {inner: outer * inner for inner in range(1, 6)}
 for outer in range(1, 4)
}

for number, multiples in tables.items():
 print(f"{number}: {multiples}")

Output:

1: {1: 1, 2: 2, 3: 3, 4: 4, 5: 5}
2: {1: 2, 2: 4, 3: 6, 4: 8, 5: 10}
3: {1: 3, 2: 6, 3: 9, 4: 12, 5: 15}

The outer comprehension iterates over range(1, 4) to create top-level keys. The inner comprehension runs for each of those and creates a dictionary mapping numbers 1 through 5 to their product. The result is a clean python multilevel dictionary built in just two lines.

You can also add filtering conditions to your python nested dict comprehension:

raw_data = {
 "product_a": {"price": 25, "stock": 0},
 "product_b": {"price": 80, "stock": 15},
 "product_c": {"price": 45, "stock": 0},
 "product_d": {"price": 60, "stock": 7}
}

in_stock = {
 name: details
 for name, details in raw_data.items()
 if details["stock"] > 0
}

print(in_stock)

Output:

{'product_b': {'price': 80, 'stock': 15}, 'product_d': {'price': 60, 'stock': 7}}

The condition if details["stock"] > 0 filters out products with zero stock, producing a new nested dictionary python with only the available items. This is a practical real-world pattern — build a filtered subset of a larger nested dataset in one clean expression.

Full Working Example

This final example brings together everything covered — creating a python nested dictionary, accessing nested values, updating entries, safe access with .get(), and iterating through layers.

students = {
 "S001": {
 "name": "Priya Sharma",
 "age": 20,
 "grades": {
 "math": 88,
 "physics": 76,
 "programming": 95
 }
 },
 "S002": {
 "name": "Leo Novak",
 "age": 22,
 "grades": {
 "math": 91,
 "physics": 84,
 "programming": 79
 }
 },
 "S003": {
 "name": "Amara Diallo",
 "age": 21,
 "grades": {
 "math": 73,
 "physics": 68,
 "programming": 90
 }
 }
}

# Add a new student to the python nested dictionary
students["S004"] = {
 "name": "Kenji Watanabe",
 "age": 23,
 "grades": {
 "math": 85,
 "physics": 90,
 "programming": 88
 }
}

# Update an existing nested value
students["S001"]["grades"]["math"] = 92

# Safely access a grade that might not exist
chemistry = students["S002"].get("grades", {}).get("chemistry", "Not enrolled")

# Compute and display average grades for each student
print("=" * 45)
print(f"{'ID':<8}{'Name':<18}{'Average'}")
print("=" * 45)

for student_id, info in students.items():
 grades = info["grades"]
 average = sum(grades.values()) / len(grades)
 print(f"{student_id:<8}{info['name']:<18}{average:.1f}")

print("=" * 45)
print(f"\nLeo's chemistry grade: {chemistry}")

# Iterate over a single student's nested grades
print("\nDetailed grades for Priya Sharma:")
for subject, score in students["S001"]["grades"].items():
 print(f" {subject.capitalize()}: {score}")

Output:

=============================================
ID Name Average
=============================================
S001 Priya Sharma 91.7
S002 Leo Novak 84.7
S003 Amara Diallo 77.0
S004 Kenji Watanabe 87.7
=============================================

Leo's chemistry grade: Not enrolled

Detailed grades for Priya Sharma:
 Math: 92
 Physics: 76
 Programming: 95

This example shows a complete picture of working with a python nested dictionary in a realistic scenario. The outer dictionary uses student IDs as keys, each ID maps to a second dictionary with personal info, and a third-level grades dictionary holds subject scores. You can see how creating, adding, updating, safe-accessing, and iterating all come together naturally when you build a multilevel dictionary in Python.