Make a tree structure from a path name

Viewed 248

This might be very simple, but I'm not sure what to do here. In Python, I want to go through a list like:

full_list = ["A/A/A", "A/A/B", "B/B/B", "A/C/B"]

and get a dictionary with a kind of tree structure based on these labels, like this:

dictionary = {"A:{"A":["A", "B"], "C":["B"]},"B":{"B":["B]}} 

but I'm not sure how to do it. I realize that I need some nested for loops. I know about the split() function in Python.

2 Answers

You can use recursion with collections.defaultdict:

from collections import defaultdict
def to_tree(data):
   d = defaultdict(list)
   for a, *b in data:
      d[a].append(b)
   return {a:[i for [i] in b] if all(len(i) == 1 for i in b) else to_tree(b)  
           for a, b in d.items()}

full_list = ["A/A/A", "A/A/B", "B/B/B", "A/C/B"]
result = to_tree([i.split('/') for i in full_list])

Output:

{'A': {'A': ['A', 'B'], 'C': ['B']}, 'B': {'B': ['B']}}

Making the leaf nodes list entries instead of empty dictionaries makes this trickier IMO -- I'd rethink that aspect of it.

>>> full_list = ["A/A/A", "A/A/B", "B/B/B", "A/C/B"]
>>> from collections import defaultdict
>>> dictionary = defaultdict(lambda: defaultdict(list))
>>> for entry in full_list:
...     node = dictionary
...     for path in entry.split("/"):
...         if isinstance(node, dict):
...             node = node[path]
...         else:
...             node.append(path)
...
>>> dictionary
defaultdict(<function <lambda> at 0x000001C8098171F0>, {'A': defaultdict(<class 'list'>, {'A': ['A', 'B'], 'C': ['B']}), 'B': defaultdict(<class 'list'>, {'B': ['B']})})
Related