0

Below, in my adjacency matrix method I've created 2 arrays that produce the same results, but when changing values within the arrays I get 2 different results. The one labeled "array_matrixx" was my initial attempt, but altering values within a nested list would not just change one of the list, but would in fact change all of the nested list. On the other hand, the array labeled "array_matrix" uses a different approach to filling the array with zero's, and yields the correct result of changing the indices within the correct nested lists. Why would this occur if prior to the for loop, they are identical?

I've listed all of the code needed to run the two lists to make comparisons. Just comment one or the other out.

class Node(object):
    def __init__(self, value):
        self.value = value
        self.edges = []

class Edge(object):
    def __init__(self, value, node_from, node_to):
        self.value = value
        self.node_from = node_from
        self.node_to = node_to

class Graph(object):
    def __init__(self, nodes=[], edges=[]):
        self.nodes = nodes
        self.edges = edges

    def insert_node(self, new_node_val):
        new_node = Node(new_node_val)
        self.nodes.append(new_node)
        
    def insert_edge(self, new_edge_val, node_from_val, node_to_val):
        from_found = None
        to_found = None
        for node in self.nodes:
            if node_from_val == node.value:
                from_found = node
            if node_to_val == node.value:
                to_found = node
        if from_found == None:
            from_found = Node(node_from_val)
            self.nodes.append(from_found)
        if to_found == None:
            to_found = Node(node_to_val)
            self.nodes.append(to_found)
        new_edge = Edge(new_edge_val, from_found, to_found)
        from_found.edges.append(new_edge)
        to_found.edges.append(new_edge)
        self.edges.append(new_edge)
    
    def get_adjacency_matrix(self):
        max_index = self.find_max_index()
        adjacency_matrixx = [([0] * (max_index + 1))] * (max_index + 1)
        print(adjacency_matrixx)
        adjacency_matrix = [[0 for i in range(max_index + 1)] for j in range(max_index + 1)]
        print(adjacency_matrix)
        for edge_object in self.edges:
            adjacency_matrix[edge_object.node_from.value][edge_object.node_to.value] = edge_object.value
        return adjacency_matrix
        
    
    def find_max_index(self):
        max_index = -1
        if len(self.nodes):
            for node in self.nodes:
                if node.value > max_index:
                    max_index = node.value
        return max_index

graph = Graph()
graph.insert_edge(100, 1, 2)
graph.insert_edge(101, 1, 3)
graph.insert_edge(102, 1, 4)
graph.insert_edge(103, 3, 4)

# Should be [[0, 0, 0, 0, 0], [0, 0, 100, 101, 102], [0, 0, 0, 0, 0], [0, 0, 0, 0, 103], [0, 0, 0, 0, 0]]
print(graph.get_adjacency_matrix())
  • `[([0] * (max_index + 1))] * (max_index + 1)` is problematic. In general, you shouldn't use "sequence multiplication" on sequences containing mutable objects (like other lists). The link above explains why. – Carcigenicate Sep 29 '20 at 22:04
  • Also, see [here](https://stackoverflow.com/questions/1132941/least-astonishment-and-the-mutable-default-argument) for why you shouldn't have lists in `def __init__(self, nodes=[], edges=[])`. That will bite you later too. – Carcigenicate Sep 29 '20 at 22:05

0 Answers0