1

I was trying to implement a graph using the two classes Edge and Vertex.

I don't know why when I add an exiting vertex to A it also happens to belong to H's exiting vertices.

The final print statement prints out "AE" while it shouldn't print anything.

Why is this thing happening?

class Edge:
    def __init__(self,endp_1,endp_2,weight):
        self.endp_1=endp_1
        self.endp_2=endp_2
        self.weight=weight
    def __str__(self):
        return str(self.endp_1)+str(self.endp_2)

class Vertex:
    def __init__(self,name,exiting_edges=[],cost=float("inf")):
        self.name=name
        self.exiting_edges=exiting_edges
        self.cost=cost
    def add_exiting_edge(self,vertex,weight):
        self.exiting_edges.append(Edge(self,vertex,weight))
    def __str__(self):
        return self.name

A=Vertex("A")
B=Vertex("B")
C=Vertex("C")
D=Vertex("D")
E=Vertex("E")
F=Vertex("F")
G=Vertex("G")
H=Vertex("H")
vertices=[A,B,C,D,E,F,G,H]

A.add_exiting_edge(E,12)
for edge in H.exiting_edges:
    print(edge)

1 Answers1

0

Solution #1 : a cleaned up init

Declaring the variables inside the class declaration makes them class members and not instance members. Declaring them inside the __init__ method makes sure that a new instance of the members is created alongside every new instance of the object.

class Vertex:
    def __init__(self, name):
        self.name=name
        self.exiting_edges=[]
        self.cost=float("inf")

    def add_exiting_edge(self, vertex, weight):
        self.exiting_edges.append(Edge(self, vertex, weight))
        
    def __str__(self):
        return self.name

Then if you do :

>>> A=Vertex("A")
>>> H=Vertex("H")
>>> E=Vertex("E")
>>> A.add_exiting_edge(E,12)
>>> for edge in A.exiting_edges:
...     print(edge)
AE

You get AE as you added the existing edge E to A.

And if you check for H :

>>> for edge in H.exiting_edges:
...     print(edge)

It return nothing as expected.

[Interesting example]

Solution #2 : keeping the default values

However, if you really want to have a default value in your __init__ you can do it like so :

class Vertex:
    def __init__(self, name, exiting_edges=None, cost=None):
        self.name=name
        if exiting_edges is None:
            exiting_edges = []
        self.exiting_edges=exiting_edges
        if cost is None:
            cost = float("inf")
        self.cost=cost

This works as expected.

You can have a look at this answer.

tlentali
  • 3,407
  • 2
  • 14
  • 21