Вот способ сделать это.Я использую другой класс узлов, чтобы немного упростить настройку:
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)]
[Edit] Обратите внимание, что это возвращает список и не изменяет узлы.
Что касается вашей конкретной реализации, вы можете подумать о том, что произойдет, если есть пустоекаталог.Это разрешено?Если так, то это лист, а не файл.Будет ли это иметь значение в этом случае?