Рекурсивная функция для деревьев в Python
Я пытаюсь сделать функцию в Python, которая принимает произвольный узел дерева, и заполняет список списков на узле дают.
учитывая следующее плохо нарисованное дерево:
если мы начнем, например, с узла 5, мы должны получить:
- список, содержащий все узлы с одним родительским узлом, включая тот, с которого мы начали (4 и 5)
- любые дочерние узлы, но не их дети (6).
- родительские узлы и любые родительские узлы с одним и тем же родителем, а также их родительские узлы и т. д. пока мы не доберемся до корня, но не включая корневой узел (только 2 и 3 в этом случае, но если дерево было глубже, и мы начали снизу, было бы больше здесь.
и узлы должны оказаться в списке списков, по одному списку для каждой глубины.
узлы в python:
nodes = [
{'id': 1, 'parent': None},
{'id': 2, 'parent': 1},
{'id': 3, 'parent': 1},
{'id': 4, 'parent': 2},
{'id': 5, 'parent': 2},
{'id': 6, 'parent': 5},
{'id': 7, 'parent': 6},
{'id': 8, 'parent': 3}
]
мы можем видеть только родителей, а не детей, но это данные формат, с которым мне приходится работать, к сожалению.
Итак, если мы возьмем узел 5, мы хотим, чтобы список узлов выглядел примерно так:
nl = [
[{'id': 6, 'parent': 5}],
[{'id': 4, 'parent': 2}, {'id': 5, 'parent': 2}],
[{'id': 2, 'parent': 1}, {'id': 3, 'parent': 1}],
]
это код у меня есть до сих пор. Я полагаю, что рекурсивная функция, вероятно, является самым простым способом. К сожалению, он, кажется, не делает ничего такого, что я думаю, и, очевидно, я делаю что-то очень неправильно. И этот код даже не рассматривает получение дочерних узлов, с которыми я не совсем уверен, как иметь дело вообще, кроме от возможности передать потом, что было бы намного проще.
node_list = []
def pop_list(nodes=None, parent=None, node_list=None):
if parent is None:
return node_list
node_list.append([])
for node in nodes:
if node['parent'] == parent:
node_list[-1].append(node)
if node['id'] == parent:
parent = node['parent']
return pop_list(nodes, parent, node_list)
print pop_list(nodes, 5, node_list)
вот вывод:
[[], [{'id': 3, 'parent': 1}], []]
не совсем уверен, где я ошибаюсь здесь.
1 ответов
проблема
if node['id'] == parent:
parent = node['parent']
текущего parent
будет перезаписан его родителем.
кроме того, вы должны добавить return node_list
В конце функции, или использовать node_list
в качестве результата.
def pop_list(nodes=None, parent=None, node_list=None):
if parent is None:
return node_list
node_list.append([])
for node in nodes:
if node['parent'] == parent:
node_list[-1].append(node)
if node['id'] == parent:
next_parent = node['parent']
pop_list(nodes, next_parent, node_list)
return node_list
>>> print pop_list(nodes, 5, node_list)
[[{'id': 6, 'parent': 5}], [{'id': 4, 'parent': 2}, {'id': 5, 'parent': 2}], [{'id': 2, 'parent': 1}, {'id': 3, 'parent': 1}]]