Home > other >  Variable Locality
Variable Locality

Time:10-09

I'm trying to implement Dijkstra alogorthim. While doing so, I've coded graph part. I'm observing this strange output. Not sure which feature causing this. I'm getting same output for two print though one is local variable and another is in class.

class Graph(object):
def __init__(self, nodes, init_graph):
    self.nodes = nodes
    self.graph = self.construct_graph(nodes, init_graph)
def construct_graph(self, nodes, init_graph):
    '''
    This method makes sure that the graph is symmetrical.
    In other words, if there's a path from node A to B with a value V, there needs to be a path from node B to node A with a value V.
    :param self:
    :param nodes:
    :param init_graph:
    :return:
    '''
    graph = {}
    for node in nodes:
        graph[node] = {}
    graph.update(init_graph)
    for node, edges in graph.items():
        for adjacent_node, value in edges.items():
            if graph[adjacent_node].get(node, False) == False:
                graph[adjacent_node][node] = value
    print(graph)
    return graph

if __name__=="__main__":
    nodes = ["Reykjavik", "Oslo", "Moscow", "London", "Rome", "Berlin", "Belgrade", "Athens"]
    init_graph = {}
    for node in nodes:
        init_graph[node] = {}
    init_graph["Reykjavik"]["Oslo"] = 5
    init_graph["Reykjavik"]["London"] = 4
    init_graph["Oslo"]["Berlin"] = 1
    init_graph["Oslo"]["Moscow"] = 3
    init_graph["Moscow"]["Belgrade"] = 5
    init_graph["Moscow"]["Athens"] = 4
    init_graph["Athens"]["Belgrade"] = 1
    init_graph["Rome"]["Berlin"] = 2
    init_graph["Rome"]["Athens"] = 2

    graph = Graph(nodes, init_graph)

    print(init_graph)

Output :

{'Reykjavik': {'Oslo': 5, 'London': 4}, 'Oslo': {'Berlin': 1, 'Moscow': 3, 'Reykjavik': 5}, 'Moscow': {'Belgrade': 5, 'Athens': 4, 'Oslo': 3}, 'London': {'Reykjavik': 4}, 'Rome': {'Berlin': 2, 'Athens': 2}, 'Berlin': {'Oslo': 1, 'Rome': 2}, 'Belgrade': {'Moscow': 5, 'Athens': 1}, 'Athens': {'Belgrade': 1, 'Moscow': 4, 'Rome': 2}}
{'Reykjavik': {'Oslo': 5, 'London': 4}, 'Oslo': {'Berlin': 1, 'Moscow': 3, 'Reykjavik': 5}, 'Moscow': {'Belgrade': 5, 'Athens': 4, 'Oslo': 3}, 'London': {'Reykjavik': 4}, 'Rome': {'Berlin': 2, 'Athens': 2}, 'Berlin': {'Oslo': 1, 'Rome': 2}, 'Belgrade': {'Moscow': 5, 'Athens': 1}, 'Athens': {'Belgrade': 1, 'Moscow': 4, 'Rome': 2}}

Expected Output :

{'Reykjavik': {'Oslo': 5, 'London': 4}, 'Oslo': {'Berlin': 1, 'Moscow': 3, 'Reykjavik': 5}, 'Moscow': {'Belgrade': 5, 'Athens': 4, 'Oslo': 3}, 'London': {'Reykjavik': 4}, 'Rome': {'Berlin': 2, 'Athens': 2}, 'Berlin': {'Oslo': 1, 'Rome': 2}, 'Belgrade': {'Moscow': 5, 'Athens': 1}, 'Athens': {'Belgrade': 1, 'Moscow': 4, 'Rome': 2}}
{'Reykjavik': {'Oslo': 5, 'London': 4}, 'Oslo': {'Berlin': 1, 'Moscow': 3}, 'Moscow': {'Belgrade': 5, 'Athens': 4}, 'London': {}, 'Rome': {'Berlin': 2, 'Athens': 2}, 'Berlin': {}, 'Belgrade': {}, 'Athens': {'Belgrade': 1}}

CodePudding user response:

graph.update(init_graph) creates references to the nested dictionaries in init_graph rather than creating a separate copy. This allows the data in init_graph to be overwritten and is causing the strange outputs.

This fixed the issue for me:

from copy import deepcopy

graph = Graph(nodes, deepcopy(init_graph))

Here's some info on dictionary copying that was helpful for me: Copy a Python Dictionary: A Complete Guide

  • Related