2 回答
TA贡献1946条经验 获得超3个赞
方法一
递归应该起作用:
def recurse_update_value(treenode):
if not treenode.children:
return
for child in treenode.children:
recurse_update_value(child)
if all(x.value==treenode.children[0].value for x in treenode.children):
treenode.value = treenode.children[0].value
treenode.children = []
方法二
此外,如果您可以编辑 TreeNode 类,则可以将 getter 方法设置为自动更新子类。
class TreeNode:
def __init__(self, path, value=None):
self.path = path
self._value = value
self.children = []
@property
def value(self)
if not self.children:
return self._value
first_child_value = self.children[0].value
if all(x.value==first_child_value for x in self.children)
self._value = first_child_value
self.children = []
return self._value
然后,您只需调用topnode.value即可更新树。
TA贡献1777条经验 获得超10个赞
这是一种方法。我正在使用不同的节点类来使设置更容易一些:
class TreeNode:
def __init__(self, node_id, value=None):
self.node_id = node_id
self.value = value
self.children = []
def addChildren(self, *node_list):
self.children += node_list
def __repr__(self):
return f'<TreeNode(node_id={self.node_id}, value={self.value})'
__repr__()只是为了在打印时获得人类可读的实例表示。
我试图设置树来反映您的示例,但如果它不完全正确,请随时告诉我。(它可以做得更简洁,但为了清楚起见,我已经为每个对象写了一行。)
root = TreeNode('root')
dir0 = TreeNode('dir0')
dir00 = TreeNode('dir00')
file00 = TreeNode('file00', 10)
file000 = TreeNode('file000', 10)
dir1 = TreeNode('dir1')
file10 = TreeNode('file10', 5)
dir2 = TreeNode('dir2')
file20 = TreeNode('file20', 10)
file21 = TreeNode('file21', 15)
dir3 = TreeNode('dir3')
dir30 = TreeNode('dir30')
file30 = TreeNode('file30', 10)
file300 = TreeNode('file300', 15)
root.addChildren(dir0, dir1, dir2, dir3)
dir0.addChildren(dir00, file00)
dir00.addChildren(file000)
dir1.addChildren(file10)
dir2.addChildren(file20, file21)
dir3.addChildren(dir30, file30)
dir30.addChildren(file300)
现在对于递归函数:
def buildList(node):
# Return node id and value if no children
if not node.children:
return [(node.node_id, node.value)]
# Call buildList on each child and get distinct values
childitems = [item for child in node.children for item in buildList(child)]
childvalues = set(childitem[1] for childitem in childitems)
# If value is unique, return this node as if it has the unique value
if len(childvalues) == 1:
return [(node.node_id, childvalues.pop())]
# Otherwise, return all results
return childitems
这会产生以下输出:
>>> buildList(root)
[('dir0', 10),
('dir1', 5),
('file20', 10),
('file21', 15),
('dir30', 15),
('file30', 10)]
[编辑] 请注意,这将返回一个列表并且不会改变节点。
关于您的特定实现,您可能想考虑如果有一个空目录会发生什么。这是允许的吗?如果是这样,它是一片叶子,而不是一个文件。在这种情况下它会有价值吗?
添加回答
举报