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:
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!
CodePudding user response:
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
.