Python: рекурсивное создание словаря из данных «графика» (базы данных)

Иметь иерархическую структуру, отображаемую в базе данных MySQL (к которой я обращаюсь через Peewee). Я пытаюсь просмотреть данные, чтобы собрать их во вложенные словари (для окончательного преобразования в XML).

Приведенная ниже функция перемещает мои данные до родительского узла и распечатывает данные, которые я хочу структурировать в моем dict:

def build_dict(current):
    query = (ParamLevel
            .select()
            # If we are looking for parents, we are matching on child
            .join(ParamLevelParamLevels, JOIN.LEFT_OUTER, on = (ParamLevelParamLevels.parent == ParamLevel.id))
            .where(ParamLevelParamLevels.child == current)
            )

    # If we have a parent node, recurse further
    if query.exists():
        parent = query.get()
        build_dict(parent)
        print('Current ParamLevel "%s" parent: "%s"' % ( current.name, parent.name ))
    else:
        print('Found root node: %s' % current.name)

При этом он печатает это:

Found root node: polycomConfig
Current ParamLevel "device" parent: "polycomConfig"
Current ParamLevel "device.dhcp" parent: "device"
Current ParamLevel "device.dhcp.bootSrvOptType" parent: "device.dhcp"

Я ищу информацию о том, как сгенерировать следующую структуру данных:

{polycomConfig : { device : { device.dhcp : { device.dhcp.bootSrvOptType: {} } } } }

Я уверен, что это довольно просто, но я не могу реализовать рекурсивные функции.

Спасибо!

Всего 2 ответа


Сделайте это с помощью цикла while вместо рекурсии и просто создайте вложенный dict по ходу работы. В этом случае рекурсия не приносит никакой пользы.

def build_dict(current):
    print(f'Found root node {current.name}')
    temp_dict = {}
    query = (ParamLevel
            .select()
            # If we are looking for parents, we are matching on child
            .join(ParamLevelParamLevels, JOIN.LEFT_OUTER, on = (ParamLevelParamLevels.parent == ParamLevel.id))
            .where(ParamLevelParamLevels.child == current)
            )
    while query.exists():
        result = query.get()
        temp_dict = {result.name: temp_dict}
        query = (ParamLevel
            .select()
            # If we are looking for parents, we are matching on child
            .join(ParamLevelParamLevels, JOIN.LEFT_OUTER, on = (ParamLevelParamLevels.parent == ParamLevel.id))
            .where(ParamLevelParamLevels.child == result)
            )

Не имея возможности проверить это, я не могу дать вам вывод или проверить наличие ошибок, но вы должны понять суть этого. Результат, который вы хотите, должен быть в temp_dict .

Я проверил это с этим:

d = {}
for i in range(5):
    d = {i: d}
print(d)

Выход:

{4: {3: {2: {1: {0: {}}}}}}

Трудно попробовать это без хорошего примера, но я считаю, что это должно работать:

 def build_dict(current, root={}): query = ( ParamLevel.select() # If we are looking for parents, we are matching on child .join( ParamLevelParamLevels, JOIN.LEFT_OUTER, on=(ParamLevelParamLevels.parent == ParamLevel.id), ).where(ParamLevelParamLevels.child == current) ) # If we have a parent node, recurse further if query.exists(): parent = query.get() root, parent_dict = build_dict(parent, root) parent_dict[parent.name] = {current.name: {}} return root, parent_dict[parent.name] else: root[current.name] = {} return root, root answer, _ = build_dict(<starting_node>) 

Есть идеи?

10000