AttributeError: 'NoneType' object has no attribute 'data' while running a LinkedList code

Question:

This is a code to add a new node at the beginning of a linked list and then print the elements in the linked list. But when I run the program I get the following error in the last line when I call the ll1.print_LL() function:

AttributeError: ‘NoneType’ object has no attribute ‘data’

And here is my code:

class Node:
    def __init__(self, data):
        self.data = data
        self.ref = None
        
class LL:
    def __init__(self):
        self.head = None
        
    def print_LL(self):
        if self.head is None:
            print("LL is empty")
        else:
            node = self.head
            while self.head is not None:
                print(node.data)
                node = node.ref
    
    def add_begin(self, data):
        new_node = Node(data)
        new_node.ref = self.head
        
        self.head = new_node
        
        
ll1 = LL()
ll1.add_begin(10)
ll1.add_begin(20)
ll1.print_LL()

I have seen a post about a similar error on StackOverflow, but I’m still confused.
Why am I getting this error in my code and how do I fix it?

Asked By: Anonymous Stranger

||

Answers:

Short Answer:
Change while self.head is not None:
to
while node is not None:

Explanation*
The error message tells you something that you might think of. It tells you that at some point you’re trying to get ".data" from a None variable, which means your loops at "some point" reach None.

Now, the issue is at this part

 def print_LL(self):
        if self.head is None:
            print("LL is empty")
        else:
            node = self.head
            while self.head is not None:
                print(node.data)
                node = node.ref

Here, you are assigning node = self.head which is making the pointer point to the first element (the head), and you WANT to make the pointer move forward, which what you’re doing when you said: node=node.ref, however, your test condition is not correct, because you’re testing against self.head.

Since self.head is never gonna be None, it will keep looping forever, but the node will keep moving forward and return a None error because there are no more nodes.

The answer:

Change the while loop to:

    def print_LL(self):
        if self.head is None:
            print("LL is empty")
        else:
            node = self.head
            while node is not None:
                print(node.data)
                node = node.ref
Answered By: Mahmoud amr

While the breaking error has been pointed out in the answer, there is another intricacy worth considering, add_begin() function should be changed to:

      def add_begin(self,data):
        new_node = Node(data)
        if self.head is None:
          self.head = new_node
        else:
          new_node.ref = self.head
          self.head = new_node

.because when the first time you call add_begin() function, there is no value in head and as such the line

new_node.ref = self.head is meaningless as it is assigning None value to None value.

Also it improves code readability.

Answered By: azzam
Categories: questions Tags:
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.