Compact Paths

A CompactPathsView expresses the same set of paths as a PathsView, but in a factorised form that groups siblings under their shared parent. This makes the structure easier to read and inspect at a glance.

The compact structure format

The compact form is a Python list where each element represents a branch of the dictionary tree:

  • A leaf (a node with no children) is represented by its key alone.

  • An internal node (a node with children) is represented as a list [key, child1, child2, ...], where each child follows the same rule recursively.

For the dictionary {"a": {"b": 1, "c": 2}, "d": 3} the compact structure is:

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

Reading it: 'a' has two children 'b' and 'c'; 'd' is a leaf.

The full expanded paths ['a'], ['a', 'b'], ['a', 'c'], ['d'] can be recovered exactly from this compact form — the mapping is bijective.

Obtaining a compact paths view

from ndict_tools import NestedDictionary

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

Reading the structure

cpaths.structure
# [['a', 'b', 'c'], ['d']]

Expanding to full paths

expand() reconstructs all paths from the compact structure:

cpaths.expand()
# [['a'], ['a', 'b'], ['a', 'c'], ['d']]

Iterating a CompactPathsView directly yields the same result (inherited from PathsView):

list(cpaths)
# [['a'], ['a', 'b'], ['a', 'c'], ['d']]

Setting a custom structure

The structure attribute is writable. You can assign a hand-crafted compact structure and then expand or analyse it:

cpaths.structure = [['a', 'b']]   # only two of the original four paths

cpaths.expand()
# [['a'], ['a', 'b']]

You can also assign a NestedDictionary directly to rebuild the structure from a different source:

nd2 = NestedDictionary({"x": {"y": 1, "z": 2}})
cpaths.structure = nd2
cpaths.structure
# [['x', 'y', 'z']]

Converting between views

Both view classes can be converted to the other in one step:

# PathsView → CompactPathsView
paths  = nd.paths()
cpaths = paths.to_compact()

# CompactPathsView → PathsView
paths2 = cpaths.to_paths()

Deeper nesting example

The compact format handles arbitrary depth. Given:

nd = NestedDictionary({
    "europe": {
        "france": {"capital": "Paris"},
        "germany": {"capital": "Berlin"},
    },
    "asia": {"japan": {"capital": "Tokyo"}},
})

nd.compact_paths().structure
# [['europe', ['france', 'capital'], ['germany', 'capital']],
#  ['asia', ['japan', 'capital']]]

Each branch is factorised: 'europe' groups its two country sub-branches, each of which groups its single 'capital' leaf.