Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Python – How to convert a List into an Adjacency List for graphs structure

My problem is that I can’t convert a graph constructed through a list into a graph constructed as a dictionary, which must act as an adjacency list.

I have already constructed a random generated graph by randomly adding to each edge: start node (string), end node (string), weight (int).
But now I would need to convert it to a graph like this (a dictionary) that represent an adjacency list:

example_graph = {
        'A': {'B': 2, 'C': 3},
        'B': {'A': 2, 'C': 1, 'D': 1, 'E': 4},
        'C': {'A': 3, 'B': 1, 'F': 5},
        'D': {'B': 1, 'E': 1},
        'E': {'B': 4, 'D': 1, 'F': 1},
        'F': {'C': 5, 'E': 1, 'G': 1},
        'G': {'F': 1},
    }

These graphs must be the same, that’s why i need to convert the first one.
So what I did then is to put those three initial values (start node, end node, weight) into a list called graphConvert like this:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

        while i < graph.numberOfNodes():
        graphConvert.insert(i, list(zip(graph.edges[i].node1.printSingleNode(), graph.edges[i].node2.printSingleNode(), [graph.edges[i].weight])))

        deleteIntegers.append(graph.edges[i].weight)
        i += 1
    deleteIntegers = list(set(deleteIntegers))

That’s an example of the result: [[(‘C’, ‘B’, 4)], [(‘A’, ‘D’, 2)], [(‘D’, ‘C’, 3)], [(‘A’, ‘C’, 4)]]

Then i added this code to convert the list into a dictionary:

adj_list = {}
    for edge_list in graphConvert:
        for edge in edge_list:
            for vertex in edge:
                adj_list.setdefault(vertex, set()).update((set(edge) - {vertex}))

    for i in range(deleteIntegers.__len__()):
        adj_list.__delitem__(deleteIntegers[i])

That’s the result: {‘C’: {‘B’, 3, 4, ‘D’, ‘A’}, ‘B’: {‘C’, 4}, ‘A’: {‘C’, 2, ‘D’, 4}, ‘D’: {3, ‘C’, 2, ‘A’}}

I was hoping to obtain something like this: {‘C’: {‘B’: 4, ‘D’: 3, ‘A’: 4}, ‘B’: {‘C’: 4}, ‘A’: {‘D’: 2, ‘C’: 4}, etc. etc.

But as you can see the results are incorrect, and I can’t figure out how I can solve this problem. For example, I don’t understand how I can stop the for loop before it gets to the node’s weight and print it without sense, however then I would have to insert it afterwards to correctly display the distance between the starting and ending node.
But that is just one of the things I am not understanding and what is wrong with the program.
I’ve been banging my head about it for a while now and I’m not getting the hang of it, maybe I need a rest!
I haven’t been using python that long, so I still have a lot to learn.
Thank you so much in advance to anyone who answers me!

>Solution :

You can use a defaultdict:

from collections import defaultdict

graph_to_convert = [[('C', 'B', 4)], [('A', 'D', 2)], [('D', 'C', 3)], [('A', 'C', 4)]]
g = defaultdict(dict)

for edge in graph_to_convert:
    a,b,w = edge[0]
    g[a][b] = w

print(g)

#defaultdict(<class 'dict'>, {'C': {'B': 4}, 'A': {'D': 2, 'C': 4}, 'D': {'C': 3}})

If you aren’t happy with having a defaultdict as the final product, you can add the line g = dict(g) to cast the result to a straight dict.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading