Paths

A path is the ordered list of keys that leads from the root of a nested dictionary to any node — intermediate or leaf. For example, in:

{"a": {"b": 1, "c": 2}, "d": 3}

the paths are ['a'], ['a', 'b'], ['a', 'c'], and ['d'].

Standard Python gives you no direct way to enumerate them. ndict-tools exposes all paths through a lazy view object: PathsView.

Obtaining a paths view

Call paths() on any NestedDictionary:

from ndict_tools import NestedDictionary

nd = NestedDictionary({"a": {"b": 1, "c": 2}, "d": 3})
paths = nd.paths()

The view is lazy: no paths are materialised in memory until you actually iterate or query the view. The underlying tree is built once on first access and reused for all subsequent operations.

Iterating over paths

for path in paths:
    print(path)

# ['a']
# ['a', 'b']
# ['a', 'c']
# ['d']

Paths are yielded in depth-first, pre-order — each node before its children.

Counting paths

len(paths)   # 4

Membership testing

Membership testing uses the internal tree structure and does not iterate all paths:

['a', 'b'] in paths    # True
['a', 'z'] in paths    # False
['d'] in paths         # True

Filtering paths

Pass a predicate to keep only the paths that match a condition:

# Paths deeper than one level
paths.filter_paths(lambda p: len(p) > 1)
# [['a', 'b'], ['a', 'c']]

# Paths that contain the key 'b'
paths.filter_paths(lambda p: 'b' in p)
# [['a', 'b']]

Converting to compact form

A PathsView can be converted to a CompactPathsView in one step:

compact = paths.to_compact()
compact.structure   # [['a', 'b', 'c'], ['d']]

See Compact Paths for the full picture.

Equality

Two PathsView objects are equal when they contain the same set of paths, regardless of order:

nd2 = NestedDictionary({"d": 3, "a": {"c": 2, "b": 1}})
nd.paths() == nd2.paths()   # True