Search code examples
pythonrichanytreetreelib

get tree view from a dictionary with anytree or rich, or treelib


I read the manual from https://anytree.readthedocs.io/en/latest/#, but I didn't figure out how to translate a dictionary to tree view, anyone can help?

data = {
    'Marc': 'Udo',
    'Lian': 'Marc',
    'Dan': 'Udo',
    'Jet': 'Dan',
    'Jan': 'Dan',
    'Joe': 'Dan',
}

output is

Udo
├── Marc
│   └── Lian
└── Dan
    ├── Jet
    ├── Jan
    └── Joe

Solution

  • First you need to create the tree from your dict of "relationship" data, there are many ways to do this but here's an example:

    from anytree import Node
    
    nodes = {}
    for k, v in data.items():
        nk = nodes[k] = nodes.get(k) or Node(k)
        nv = nodes[v] = nodes.get(v) or Node(v)
        nk.parent = nv
    

    Now you need to identify the root node, in your case it is the unique node which has no parent (Udo).

    [root] = [n for n in nodes.values() if n.parent is None]
    
    # Or, if you don't need the validation that there is a unique root:
    root = <any node>
    while root.parent is not None:
        root = root.parent
    
    # Or, if you already knew the root node's name then just:
    root = nodes[root_name]
    

    Once you have the root node, you can render the tree like this:

    >>> from anytree import RenderTree
    >>> print(RenderTree(root).by_attr())
    Udo
    ├── Marc
    │   └── Lian
    └── Dan
        ├── Jet
        ├── Jan
        └── Joe
    

    The anytree API is richer than rich, so it's a little more complicated with rich.tree:

    >>> import rich.tree
    >>> nodes = {}
    ... for k, v in data.items():
    ...     nk = nodes[k] = nodes.get(k) or rich.tree.Tree(k)
    ...     nv = nodes[v] = nodes.get(v) or rich.tree.Tree(v)
    ...     nv.children.append(nk)
    ...     nk.parent = nv
    ... 
    >>> [root] = [n for n in nodes.values() if getattr(n, "parent", None) is None]
    >>> rich.print(root)
    Udo
    ├── Marc
    │   └── Lian
    └── Dan
        ├── Jet
        ├── Jan
        └── Joe