Reputation: 648
I understand that custom classes in Python are generally mutable. So in the example below, any changes done to the argument s
in the function inc_age
is reflected back at the calling section.
class Student:
def __init__(self, name, age):
self.name = name
self.age = age
def inc_age(s):
s.age += 1
s1 = Student("Test",5)
inc_age(s1)
print(s1.age) # 6
I tried to implement linked list in Python using custom class as shown below:
class ListNode:
def __init__(self, data=0, next=None):
self.data = data
self.next = next
def next_node(L):
L = L.next
end = ListNode(3)
mid = ListNode(2,end)
beg = ListNode(1,mid)
next_node(beg)
print(beg.data) # 1
My question is why the change in object L
in the function next_node
not observed at the calling section.
Upvotes: 0
Views: 456
Reputation: 365767
The short version is this:
L
, those will be represented in any other references to that value. L
to be a name for a completely different value, that doesn't change anything but the local variable L
.If this seems confusing to you, you're not thinking correctly about what variables in Python are. In some languages, like C++, a variable is a location where a value lives. In other languages, like Python, a variable is just a name that you can look up in a namespace to find a value; the values live wherever they want.
So, L =
doesn't do anything to whatever value L
is a name for, it just makes L
into a name, in the local namespace, for a different value.
But L.next =
would make next
into a name for a different value in the namespace of the value that L
refers to. So any other name for the same value as L
can see the change.
Upvotes: 3
Reputation: 36682
You must address attributes using self
, and avoid naming variables and attributes with the names of builtin methods (next):
The output test enumerates all nodes from the head.
class ListNode:
def __init__(self, data=0, next_node=None):
self.data = data
self.next_node = next_node
def add_next_node(self, node):
self.next_node = node
if __name__ == '__main__':
beg = ListNode(1)
mid = ListNode(2)
end = ListNode(3)
beg.add_next_node(mid)
mid.add_next_node(end)
current = beg
while True:
print(current.data)
current = current.next_node
if current is None:
break
1
2
3
Upvotes: 0