Поиск корня дерева — хороший кандидат на отдельную операцию. В вашем примере мы знаем, что это "Mary"
, поэтому мы можем выполнить соответствующую итерацию. Если это неизвестно, вы можете написать функцию для возврата первого родительского узла, который не является дочерним элементом любого другого узла:
def find_root(tree):
all_children = {x for y in tree.values() for x in y}
for node in tree:
if node not in all_children:
return node
Что касается фактической процедуры печати, попробуйте распечатать родительский узел, прежде чем перебирать дочерние узлы. Я также рекомендую передавать дерево в качестве параметра функции, чтобы сохранить инкапсуляцию и возможность повторного использования (т. е. не зависеть от некоторой переменной с именем children_and_parents
, существующей в вызывающей области).
def draw_family_tree(tree, root, gap=3, level=0):
if root:
print(" " * level + root)
if root in tree:
for child in tree[root]:
draw_family_tree(tree, child, gap, level + gap)
Мы также можем избежать побочного эффекта в draw_family_tree
и заставить его возвращать генератор, позволяя вызывающей стороне решать, что делать с результатом:
def find_root(tree):
all_children = {x for y in tree.values() for x in y}
for node in tree:
if node not in all_children:
return node
def draw_family_tree(tree, root, gap=3, level=0):
if root:
yield " " * level + root
if root in tree:
for child in tree[root]:
yield from draw_family_tree(tree, child, gap, level + gap)
if __name__ == "__main__":
children_and_parents = {
"Mary": ["Patricia", "Lisa"],
"Patricia": ["Barbara", "Helen", "Maria"],
"Maria": ["Keren", "Carol"],
"Barbara": ["Betty"]
}
root = find_root(children_and_parents)
for node in draw_family_tree(children_and_parents, root):
print(node)
Выход:
Mary
Patricia
Barbara
Betty
Helen
Maria
Keren
Carol
Lisa
Как упоминалось ранее, я не рекомендую использовать класс для простой пары <string, list>
; он добавляет много многословия без функциональности и на самом деле немного вводит в заблуждение, потому что parent
предполагает, что у человека есть родитель (на самом деле это относится к имени человека, представленного объектом). Если вы решите пойти по этому пути, вам нужно добавить .child
ко всем обращениям к скобкам и написать функцию __repr__(self)
для вашего класса (или print(root.parent)
.
person
ggorlen
schedule
27.11.2018