Find All Leaf Paths in a Nested Dict in Python

Recursively traverse a nested dictionary and yield every leaf path as a list of keys, including paths to empty dictionaries.

Medium Python 3.9+ Aug 9, 2026 Dictionaries & sets 13 views 0 copies

Python code

21 lines
Python 3.9+
def find_leaf_paths(data, path=None):
    if path is None:
        path = []
    
    if not isinstance(data, dict) or not data:
        yield path
        return
    
    for key, value in data.items():
        yield from find_leaf_paths(value, path + [key])

if __name__ == "__main__":
    nested = {
        "a": 1,
        "b": {"c": 2, "d": {"e": 3}},
        "f": {},
        "g": {"h": {"i": 4}}
    }
    
    for leaf_path in find_leaf_paths(nested):
        print(leaf_path)

Output

stdout
['a']
['b', 'c']
['b', 'd', 'e']
['f']
['g', 'h', 'i']

How it works

The function treats both non-dict values and empty dicts as leaves, so every branch terminates with a path. The path is None check avoids the mutable default argument pitfall, creating a fresh list for each top-level call. yield from recursively delegates to sub-traversals, combining paths with the + operator to build the key chain. This fits dictionary traversal patterns where you need to locate all terminal nodes in arbitrarily nested data.

Common mistakes

  • Using a mutable default argument like `path=[]`, which causes shared state across calls
  • Forgetting to treat empty dicts as leaf nodes, making the recursion miss terminal branches
  • Checking `isinstance(data, dict)` after trying to iterate, risking a TypeError on non-dict values

Variations

  1. Use a stack for an iterative depth-first traversal instead of recursion
  2. Collect all paths into a list with `list(find_leaf_paths(data))`

Real-world use cases

  • Flattening JSON API responses to map every endpoint field to a location for data migration.
  • Walking configuration dictionaries to validate every setting key and surface missing or empty leaf values.
  • Instrumenting policy or rules trees where each leaf path identifies a specific decision endpoint.

Sponsored

Run this sample

Open the browser IDE to tweak the example and see results without installing anything.

Open editor

More from Dictionaries & sets

Related tutorials and quizzes for this topic.