Python:从键,值对列表中创建任意嵌套的字典

时间:2017-07-19 02:26:46

标签: python algorithm dictionary recursion

我试图从Python中的键值对列表中创建一个任意嵌套的字典。键值对列表如下所示:

input_data = [{1:2}, {2:3}, {3:4}, {3:5}, {1:3}]

[我的实际输入数据更大,递归更多。]给定输入,目标是嵌套所有键值对,以便实现:

{1: {2: {3: {4: null}, {5: null}}}, {3: {4: null, 5: null} } }

我一直在修补一些递归功能,但仍然没有取得突破。如果其他人的想法可以帮助解决这种嵌套问题,我将非常感谢他们的建议。

1 个答案:

答案 0 :(得分:1)

您可以在两步过程中完成此操作,首先将边缘列表转换为节点到连接节点的图形:

In []:
graph = {}
for edge in inpt:
    for n1, n2 in edge.items():
        graph.setdefault(n1, []).append(n2)
graph

Out[]
{1: [2, 3], 2: [3], 3: [4, 5]}

注意:不要使用input作为变量名称,它隐藏了python的内置input()

然后创建一个递归函数来获取你正在寻找的路径是相当容易的,这里是一个递归函数,它接受一个图和起始节点并从该节点返回路径:

In []:
def paths(graph, nodes):
    if not nodes:
        return None
    return {node: paths(graph, graph.get(node, [])) for node in nodes}

paths(graph, [1])

Out[]
{1: {2: {3: {4: None, 5: None}}, 3: {4: None, 5: None}}}

注意:您的预期输出不是有效词典

或者您可以使用队列迭代地执行此操作:

In []:
def paths(graph, start):
    p = {}
    q = [(start, p, set())]
    while q:
        node, c, visited = q.pop()
        if node not in graph or node in visited:
            c[node] = None
            continue
        visited = visited | {node}
        for n in graph[node]:
            q.append((n, c.setdefault(node, {}), visited))
    return p

paths(graph, 1)

Out[]:
{1: {2: {3: {4: None, 5: None}}, 3: {4: None, 5: None}}}

注意:这需要一个有向的非循环图,否则它会递归到python失败 - 这需要额外的检查才能避免。