Skip to content

Instantly share code, notes, and snippets.

@dtranhuusm
Last active October 12, 2018 19:13
Show Gist options
  • Save dtranhuusm/27aa54c806c474aaf7dc6b13b06a28ac to your computer and use it in GitHub Desktop.
Save dtranhuusm/27aa54c806c474aaf7dc6b13b06a28ac to your computer and use it in GitHub Desktop.
Convert tree string to dictionary
""" Function to convert a tree in string format to a dictionary.
There is no error handling.
It doesn't allow a level to be skipped.
"""
def tree_child(acc, path, element):
node = element.lstrip()
current = None
for p in path:
if current:
current = current[p]
else:
current = acc[p]
current[node] = dict()
return node
def tree_sibling(acc, path, element):
return tree_child(acc, path[:-1], element)
def _parse_tree(acc, path, indent, tree_ls):
""" Recursive function parsing a list.
Args:
acc(dictionary): accumulator dictionary used both as in-out
path(list): current node
indent(str): indentation value used to identify depth of tree
tree_ls(list): list of lines indented following indent
Returns:
dictionary: dictionary corresponding to tree_ls provided
"""
#print(acc, path)
if tree_ls:
line = tree_ls[0].rstrip()
if not line:
return _parse_tree(acc, path, indent, tree_ls[1:])
if not path:
node = line.lstrip()
acc[node] = dict()
return _parse_tree(acc, [node], indent, tree_ls[1:])
next_indent = indent * len(path)
current_indent = next_indent[:-len(indent)]
if len(line) > len(next_indent) and line[:len(next_indent)]==next_indent:
node = tree_child(acc, path, line[len(next_indent):])
return _parse_tree(acc, path+[node], indent, tree_ls[1:])
if len(line) > len(current_indent) and line[:len(current_indent)]==current_indent:
node = tree_sibling(acc, path, line[len(current_indent):])
return _parse_tree(acc, path[:-1]+[node], indent, tree_ls[1:])
# back up the tree and parse recursively
return _parse_tree(acc, path[:-1], indent, tree_ls)
# end of recursion
return acc
def parse_tree(tree_st, indent):
res = dict()
path = []
val_ls = tree_st.split('\n')
return _parse_tree(res, path, indent, val_ls)
if __name__=="__main__":
tree = """
one
one
one
two
two
one
three
one
two
three
"""
print(parse_tree(tree, " "))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment