我有一些数据(Pythonlist
of dict
s) 看起来像:
[
{'value': 'A', 'level': 0},
{'value': 'B', 'level': 1},
{'value': 'C', 'level': 2},
{'value': 'D', 'level': 1},
{'value': 'E', 'level': 2},
{'value': 'F', 'level': 2},
{'value': 'G', 'level': 0},
{'value': 'H', 'level': 1},
...
]
它代表一棵树,看起来像:
<root>
|
+---A
| |
| +---B
| | |
| | +---C
| |
| +---D
| |
| +---E
| |
| +---F
+---G
|
+---H
这是我想要的是:高效、优雅(Pythonic?)的方法从仅具有级别(换句话说,深度)的数组构造树。
这样我就可以访问树:
root = build_tree(data) # or somewhat proper arguments
print(root.children) # => [<Node A>, <Node G>]
print(root.children[0].children) # => [<Node B>, <Node D>]
print(root.children[0].children[1].children]) # => [<Node E>, <Node F>]
print(root.children[1].children) # => [Node G]
print(root.children[1].children[0].children) # => []
我努力编写一些递归函数来实现它,但突然我的大脑停止了工作。我正在等待你的帮助。
谢谢。
--- 已编辑 ---
这是我写的:
class TreeNode(object):
def __init__(self, parent, value):
self.parent = parent
self.children = []
self.__dict__.update(**value)
def __repr__(self):
return '<TreeNode %s>' % self.value
def build_tree(list, parent, start_idx=0, depth=0):
current = TreeNode(parent, list[start_idx])
parent.children.append(current)
for idx in xrange(start_idx + 1, len(list)):
if list[idx]['level'] == current.level:
build_tree(list, parent, idx)
elif list[idx]['level'] == current.level + 1:
build_tree(list, current, idx)
elif list[idx]['level'] < current.level:
break
def print_tree(root, depth=0):
for child in root.children:
print(' ' * depth + '%r' % child)
print_tree(child, depth + 1)
if __name__ == '__main__':
data = [
{'value': 'A', 'level': 0},
{'value': 'B', 'level': 1},
{'value': 'C', 'level': 2},
{'value': 'D', 'level': 1},
{'value': 'E', 'level': 2},
{'value': 'F', 'level': 2},
{'value': 'G', 'level': 0},
{'value': 'H', 'level': 1},
]
root = TreeNode(None, {'value': 'root'})
build_tree(data, root)
print_tree(root)
它给出:
<TreeNode A>
<TreeNode B>
<TreeNode C>
<TreeNode E>
<TreeNode F>
<TreeNode F>
<TreeNode D>
<TreeNode E>
<TreeNode F>
<TreeNode F>
<TreeNode D>
<TreeNode E>
<TreeNode F>
<TreeNode F>
<TreeNode H>
<TreeNode G>
<TreeNode H>