0

I'm studying about graphs and python isn't working as it should on one thing.

I'm writing the removeVertex function like this:

def remove_vertex(self, vertex):
    cities = self.adjacencyList[vertex] # Cities is an array ["mexico", "japan"]
    for city in cities: 
        self.remove_edge(vertex, city)
    self.adjacencyList.pop(vertex, None)
    return True

Basically im looping through the adjacency list of a vertex and removing all the edges of it, my graph is unweighted and undirectional.

This is my full code for the class:

class Graph:
def __init__(self):
    self.adjacencyList = {}

def add_vertex(self, name):
    if name not in self.adjacencyList.keys():
        self.adjacencyList[name] = []
        return True
    else:
        return False

def add_edge(self, vertex_a, vertex_b):
    self.adjacencyList[vertex_a].append(vertex_b)
    self.adjacencyList[vertex_b].append(vertex_a)

def remove_edge(self, vertex_a, vertex_b):
    self.adjacencyList[vertex_a].remove(vertex_b)
    self.adjacencyList[vertex_b].remove(vertex_a)
    return True

def remove_vertex(self, vertex):
    cities = self.adjacencyList[vertex]
    for city in cities:
        self.remove_edge(vertex, city)
    self.adjacencyList.pop(vertex, None)
    return True

And this my main code:

graph = Graph()
graph.add_vertex("mexico")
graph.add_vertex("china")
graph.add_vertex("japon")
graph.add_edge("mexico", "china")
graph.add_edge("japon", "mexico")
graph.add_edge("japon", "china")
graph.remove_vertex("japon") # This is where the error occurs

So when I call the last function the class method remove vertex only removes the edges from the vertex to remove and the first city it has a connection, such as "mexico" but it doesnt remove the second or others because the loop it breaks here in the for x in arr.

def remove_vertex(self, vertex):
cities = self.adjacencyList[vertex] # Cities is an array ["mexico", "japan"]
for city in cities: 
    self.remove_edge(vertex, city)
self.adjacencyList.pop(vertex, None)
return True

What am I doing wrong?

1 Answers1

1

When you iterate through this for loop:

for city in cities: 
    self.remove_edge(vertex, city)

You change the list cities while you are iterating through it.

Python starts at the first element of cities. It removes "mexico" from cities. Python then moves to the next element of cities. It finds there is no second element, so it exits the for loop - even though it has not iterated through the others.

What you want to do is make a copy of self.adjacencyList[vertex], and iterate through the copy:

def remove_vertex(self, vertex):
    cities = self.adjacencyList[vertex].copy()
    for city in cities:
        self.remove_edge(vertex, city)
    self.adjacencyList.pop(vertex, None)
    print(self.adjacencyList) # prints {'mexico': ['china'], 'china': ['mexico']}
    return True
knosmos
  • 636
  • 6
  • 17