简体   繁体   中英

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. 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()

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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