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

Question:

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
Asked By: user1334609

||

Answers:

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
Answered By: wim
Categories: questions Tags: , , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.