简体   繁体   English

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

[英]Create arbitrarily nested dictionary from list of key, value pairs

I'm trying to create an arbitrarily nested dictionary from a list of key, value pairs in Python.我正在尝试从 Python 中的键值对列表创建一个任意嵌套的字典。 The list of key value pairs looks like this:键值对列表如下所示:

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

[My actual input data is much larger and has much more recursion.] Given that input, the goal is to nest all key value pairs, so that one achieves: [我的实际输入数据要大得多,并且具有更多的递归。] 鉴于该输入,目标是嵌套所有键值对,以便实现:

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

I have been tinkering with some recursive functions but still haven't hit a breakthrough.我一直在修改一些递归函数,但仍然没有取得突破。 If others have ideas that could help solve this kind of nesting problem, I'd be very grateful for their suggestions.如果其他人有可以帮助解决这种嵌套问题的想法,我将非常感谢他们的建议。

You can do this in a 2 step process, first convert the list of edges to a graph of node to connected nodes:您可以分两步执行此操作,首先将边列表转换为节点图到连接节点:

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]}

Note: don't use input as a variable name it hides python's builtin input()注意:不要使用input作为变量名它隐藏了 python 的内置input()

Then it is reasonably easy to create a recursive function to get the paths you are looking for, here's a recursive function that takes a graph and starting node and returns the paths from that node:然后创建一个递归函数来获取您正在寻找的路径是相当容易的,这是一个递归函数,它接受一个图形和起始节点并返回该节点的路径:

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}}}

Note: your expected output isn't a valid dictionary注意:您的预期输出不是有效的字典

Or you can do this iteratively using a queue:或者您可以使用队列迭代地执行此操作:

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}}}

Note: this requires a directed non-cyclical graph or it will recurse until python fails - which would need additional checks to avoid.注意:这需要一个有向非循环图,否则它将递归直到 python 失败——这需要额外的检查来避免。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM