Python:从“图形”(数据库)数据递归创建字典

时间:2019-05-18 00:40:15

标签: python python-3.x dictionary recursion peewee

A在MySQL数据库中映射了一个层次结构(我正在通过Peewee访问)。我试图遍历数据以将其重新组装为嵌套字典(以最终转换为XML)。

下面的函数将我的数据向下移动到父节点,并打印出我想在字典中构建的数据:

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 个答案:

答案 0 :(得分:1)

使用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: {}}}}}}

答案 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>)