How do you create nested dict in Python?
Data Structures & Algorithms practice on Codemia
Step through 300 algorithm problems with animated visualisers that show the data structure changing as the code runs.
Introduction
A nested dictionary is a dictionary where values are themselves dictionaries, creating a tree-like hierarchy. This structure naturally represents JSON data, configuration files, database records with related fields, and any data with parent-child relationships. Python provides several ways to create and work with nested dicts — from literal syntax to defaultdict for auto-vivification.
Method 1: Literal Syntax
The simplest approach — define the entire structure inline:
Method 2: Building Incrementally
Create the outer dict first, then assign inner dicts:
This approach requires creating intermediate dicts manually. Assigning config['database']['host'] fails with a KeyError if config['database'] does not exist yet.
Method 3: defaultdict for Auto-Vivification
collections.defaultdict automatically creates missing keys, eliminating the need to pre-initialize intermediate dicts:
For arbitrary depth nesting, define a recursive defaultdict:
To convert back to regular dicts (e.g., for JSON serialization):
Method 4: dict.setdefault
setdefault creates a key with a default value if it does not exist, then returns the value:
This is verbose but works without importing anything.
Method 5: Dictionary Comprehension
Build nested dicts from existing data:
Accessing and Modifying Nested Dicts
Merging Nested Dicts
Python's dict.update() and {**a, **b} only merge at the top level. For deep merging:
Common Pitfalls
- KeyError on missing intermediate keys:
data['a']['b'] = 1fails ifdata['a']does not exist. Usedefaultdict,setdefault, or check withif 'a' not in data: data['a'] = {}first. - Mutable default arguments: Never use
def f(d={})— the same dict is shared across all calls. Usedef f(d=None): d = d or {}instead. - Shallow copy trap:
copy()and{**d}only copy the top level. Nested dicts still share references. Usecopy.deepcopy()for independent copies. - defaultdict creates keys on read: Accessing
d['missing']on adefaultdictcreates the key with the default value. This can silently grow the dict. Use.get()for read-only access or convert to a regular dict when done building. - JSON compatibility:
defaultdictis not directly JSON-serializable. Convert to regular dict withdict(d)(shallow) or a recursive converter before callingjson.dumps.
Summary
- Use literal syntax
{'key': {'nested': 'value'}}for static, known structures - Use
defaultdict(dict)for one-level auto-vivification when building dicts incrementally - Use a recursive
defaultdictfactory for arbitrary-depth nesting without pre-initialization - Use
dict.setdefault()for occasional nested key creation without imports - Use
copy.deepcopy()when you need an independent copy of a nested dict - Always use
.get()with defaults for safe access to potentially missing nested keys
Related reading
- How do you determine if two HashSets are equal by value, not by reference?
- How do you divide each element in a list by an int?
- How do you extract a column from a multi-dimensional array?
- How do you find the sum of all the numbers in an array in Java?
- How do you decode Base64 data in Python?
- How do you express binary literals in Python?
- How do you get the width and height of a multi-dimensional array?
- How do you implement a Stack and a Queue in JavaScript?

DSA Fundamentals
Master algorithmic patterns and data structures through hands-on LeetCode-style problems - from arrays and hashing to dynamic programming and advanced graphs.
View the courseTrack what you have practised
A free account saves your progress, solutions and study plan across every problem on Codemia.
Data Structures & Algorithms practice on Codemia
Step through 300 algorithm problems with animated visualisers that show the data structure changing as the code runs.