Как создать вложенный список родительских/дочерних объектов с помощью функции?
Я новичок в Python и Django и столкнулся с проблемой, которую не могу решить самостоятельно уже довольно долгое время.
У меня есть база данных, состоящая из множества объектов, и каждый объект имеет одного родителя (кроме первого, "корневого" объекта) и ни одного / одного / нескольких детей. Мне нужно создать функцию, которая принимает некоторый объект и возвращает этот объект и рекурсивно его потомков следующим образом:
arr = ['States',
['Kansas', ['Lawrence', 'Topeka', ['Some Topeka Street', ['Some House on Some Topeka Street']]],
'Illinois', ['Chicago', 'Springfield']]]
Я хочу получить такую структуру данных и использовать ее в фильтре Django unordered list.
Насколько я разбираюсь в алгоритмах, я должен составить функцию, которая каким-то образом должна работать следующим образом:
def make_nested_list(item):
if not item.children: # basic case
# do something
else:
for child in item.children: # recursive case
# do something
make_nested_list(child) # function calls itself
# maybe do something here
# and finally return self-nested list
return result
Все, что я пробую, оказывается беспорядочным. Как я могу это сделать?
Предполагая, что ваши item
объекты имеют name
атрибуты, вот что вы можете сделать:
def list_nodes(siblings):
for node in siblings:
yield node.name
if node.children:
yield list(list_nodes(node.children))
Итак, аргументом этой функции является список узлов. Если у вас только один корневой объект, то сначала поместите его в список и передайте его в качестве аргумента:
result = list(list_nodes([root]))
Вот тест, который я выполнил, включающий создание макетных данных:
from collections import namedtuple
Node = namedtuple("Node", "name, children")
root = Node("States", [
Node("Kansas", [
Node("Lawrence", []),
Node("Topeka", [])
]),
Node("Illinois", [])
])
print(root)
def list_nodes(siblings):
for node in siblings:
yield node.name
if node.children:
yield list(list_nodes(node.children))
result = list(list_nodes([root]))
print(result)
Вывод (с некоторым форматированием):
Node(name='States', children=[
Node(name='Kansas', children=[
Node(name='Lawrence', children=[]),
Node(name='Topeka', children=[])
]),
Node(name='Illinois', children=[])
])
['States', ['Kansas', ['Lawrence', 'Topeka'], 'Illinois']]