[英]Construct a tree from a list with levels
我有一些数据( dict
的Python list
),看起来像:
[
{'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>
代码应该很简单。 你的计划意味着孩子们有一个订单,所以我会使用一个list
。
In [8]: class Node:
...: def __init__(self, val=None):
...: self.value = val
...: self.children = []
...: def __repr__(self):
...: return "<Node {}>".format(self.value)
...:
算法也很简单。 从根开始。 迭代数据。 虽然您的节点深度低于"level"
节点,但继续向下移动子节点,直到最后一个子节点,尝试沿着子节点中的最后一个节点向下移动。 如果尝试索引到最后一个子节点失败,那么我们知道我们必须在哪里(假设输入表现良好!)并且我们追加一个值为"value"
的新节点。 如果没有失败并使其达到"level"
,请附加值为"value"
的新节点。 返回根并重复,而不是迭代数据。
In [9]: root = Node()
In [10]: for record in data:
...: last = root
...: for _ in range(record['level']):
...: last = last.children[-1]
...: last.children.append(Node(record['value']))
...:
现在,看看我们的树:
In [12]: root.children
Out[12]: [<Node A>, <Node G>]
In [13]: root.children[0].children
Out[13]: [<Node B>, <Node D>]
In [14]: root.children[0].children[1].children
Out[14]: [<Node E>, <Node F>]
In [15]: root.children[1].children
Out[15]: [<Node H>]
In [16]: root.children[1].children[0].children
Out[16]: []
使用方便的print_tree
函数:
In [24]: def print_tree(root, depth=0):
...: for child in root.children:
...: print(' ' * depth + '%r' % child)
...: print_tree(child, depth + 1)
...:
In [25]: print_tree(root)
<Node A>
<Node B>
<Node C>
<Node D>
<Node E>
<Node F>
<Node G>
<Node H>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.