The error occurs because you have head.next = newval
where newval
is a number, but you should be assigning a node instance, i.e. newnode
. So the next time you iterate the list, like in print_list
you'll bump into that integer, and access its data
attribute, as if it is a node...
Some other remarks on your code:
Your linkedlist
class has no state. It merely provides some functions that act on the head
argument. The OOP way to do this, is to give a linkedlist
instance its own head
attribute. And then rely on the self
argument, which in your current code is not used in the functions.
Your main code should not have to deal with node
instances. It should just have to create a linkedlist
, and then populate it by calling its method(s). For that to work you'll have to deal with the case where the list is empty, and a first value is added to it, because then its head
attribute needs to be set to it.
Use PascalCase for naming your classes.
The name of the print_list
function is misleading: it doesn't print, but returns a list. So I would name it to_list
instead.
Don't print the result of calling vals.add_at_end
, because it is not designed to return anything, so you'll be printing None
.
Corrected:
class Node(): # Use PascalCase
def __init__(self, data):
self.data = data
self.next = None
class LinkedList():
def __init__(self):
self.head = None # Give each instance its own head attribute
def add_at_end(self, newval):
if not self.head: # Deal with this case
self.head = Node(newval)
else:
head = self.head # Use attribute
while head.next:
head = head.next
head.next = Node(newval) # corrected
def to_list(self): # Better name
LL = []
head = self.head # Use attribute
while head:
LL.append(head.data)
head = head.next
return LL
vals = LinkedList()
vals.add_at_end(5) # Use method to add nodes
vals.add_at_end(6)
vals.add_at_end(2)
vals.add_at_end(8) # Nothing to print here
print(vals.to_list())