DireVish
DireVish

Reputation: 1

List.append replaces all the elements with the latest element

I have a Node class, which has a name and an array in it, and a Graph class which should have an array of Node objects:

class Node:
    name = ""
    next = []

class Graph:
    nodes = [] # nodes is an array consisting of Node objects 

I've made a function which appends a Node object into the Graph when passed a string.


def add_new(self, new_name):
        new_node = Node
        new_node.name = new_name
        self.nodes.append(new_node)
        print("New node given name: ", new_name)
        print("New length of nodes: ", len(self.nodes))

graph2 = Graph

add_new(graph2, "Jim")
add_new(graph2, "Dwight")
add_new(graph2, "Andy")

print("Node names: ")
for i in range(0,3):
    print(graph2.nodes[i].name)

Instead of actually appending the new_node, the function seems to replace all the previous elements of the node array with the latest new_node object.

python -u "c:\Users\Vishnu\CS-Project\why.py"
New node given name:  Jim
New length of nodes:  1
New node given name:  Dwight
New length of nodes:  2
New node given name:  Andy
New length of nodes:  3
Node names:
Andy
Andy
Andy

How does this happen? Isn't new_node a local variable and shouldn't it be fresh every iteration of the function?

Upvotes: 0

Views: 536

Answers (2)

André C. Andersen
André C. Andersen

Reputation: 9375

You need to actually instantiate the Node and Graph classes.

class Node:
    def __init__(self, name):
        self.name = name

class Graph:

    def __init__(self):
        self.nodes = list()

    def add_new(self, new_name):
        new_node = Node(new_name)
        self.nodes.append(new_node)
        print("New node given name: ", new_name)
        print("New length of nodes: ", len(self.nodes))

graph2 = Graph()

graph2.add_new("Jim")
graph2.add_new("Dwight")
graph2.add_new("Andy")

print("Node names: ")
for i in range(0,3):
    print(graph2.nodes[i].name)

Remember that self is a reference to the object instantiation of your class. It is part of the class definition, and a python specifica syntax.

Creating a python object from a class, is done by simply adding () to the end of the class. In Java you have to say new as well.

You define a class like this:

class Person():
    def __init__(self, some_var):
        self.some_var = some_var
    def some_method(self, msg):
        print("He said:", msg)

Then you create an object from it like this:

my_person = Person('my_var')

Then you can use a method in it like this:

my_person.some_method('FooBar')

Upvotes: 0

brunns
brunns

Reputation: 2764

Attributes set at class level are static - that is, shared by all instances of the class. You probably want:

class Node:
    def __init__(self):
        self.name = ""
        self.next = []

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

Also, you need to call the class to instantiate - so you want new_node = Node() and graph2 = Graph().

Upvotes: 1

Related Questions