【发布时间】:2019-12-29 02:44:49
【问题描述】:
我有一个相当复杂的树结构,我想遍历和聚合值(例如求和、连接、追加......)。我希望 traverse 成为树的一种方法,而不是一个单独的函数。我可以遍历并将函数应用于每个节点,但我不知道如何更新与树关联的聚合变量。
这是我的代码的简化版本,包括一个没有聚合的节点处理程序,这是可行的。
# A tree is a node that recursively includes more nodes under it.
# More correctly the Tree is the particular node regarded as the root Node.
class Node:
def __init__(self, value):
self.value = value
self.children = []
def traverse(self, handle_node):
handle_node(self)
for child in self.children:
child.traverse(handle_node)
tree = Node('A')
tree.children.append(Node('B')) # Note we append Nodes not values!
tree.children.append(Node('C'))
tree.children[1].children.append(Node('D'))
tree.children[1].children.append(Node('E'))
# This is just an example of a node-handler.
def example_func_on_a_node(node):
print(node.value)
# Execute the node handler on every node in the tree.
tree.traverse(example_func_on_a_node)
正如预期的那样打印出来
A
B
C
D
E
但是,我想要的是聚合在一般情况下。如果我有一个返回值的节点处理程序,我如何将每个节点的值与所有先前节点的值结合起来最终返回聚合。节点处理程序需要是一个通用函数,它接受一个节点作为它的参数并返回一个值。
例如,假设我想连接上述简单示例中的值。代码应该看起来像这样,但这不起作用。
class Node2:
def __init__(self, value):
self.value = value
self.children = []
self.concat = ''
def traverse(self, handle_node):
self.concat += handle_node(self)
for child in self.children:
child.traverse(handle_node)
tree = Node2('A')
tree.children.append(Node2('B')) # Note we append Nodes not values!
tree.children.append(Node2('C'))
tree.children[1].children.append(Node2('D'))
tree.children[1].children.append(Node2('E'))
# This is a node-handler that returns a value I want to aggregate.
def example_func_on_a_node2(node):
return node.value
# Execute the node handler on every node in the tree.
tree.traverse(example_func_on_a_node2)
print(tree.concat)
我得到的答案是A,但我想要的是'ABCDE'
注意我尝试了许多变体,包括使用静态和类方法,以及非局部变量,但很可能使用不正确。
我可以看到我需要什么,但看不到聚合变量的放置位置,因此它在树周围传递并返回根节点,同时保持节点处理程序和节点类简单。
【问题讨论】: