AstroPuls3
AstroPuls3

Reputation: 1

AttributeError: 'NoneType' object has no attribute 'data' Linked List

Current code, I am trying to make a linked list and then sort the linked list in ascending order.

import random
random_nums = random.sample(range(100), 10)

class Node:
    def __init__(self, data=None, next=None):
        self.data = data
        self.next = None
    def __str__(self):
        return str(self.data)

def insertNode(data, first_node):
  current_node = first_node
  while current_node !=None:
    if data > current_node.data and data <= current_node.next.data:
      new_node = Node(data, current_node.next)
      last_node.next = new_node
      print("Inserting node: " + str(data))

    current_node = current_node.next

first_node = Node(random_nums[0], None)
for i in random_nums[1:]:
  insertNode(i, first_node)

print("Linked list values:")
current_node = first_node
while current_node != None:
    print (str(current_node.data) + " => ", end="")
    current_node = current_node.next

input()

Currently getting the error

File "python", line 25, in File "python", line 16, in insertNode AttributeError: 'NoneType' object has no attribute 'data'

I am really new to python and trying to get this to work, any suggestions?

Upvotes: 0

Views: 1235

Answers (1)

MisterMiyagi
MisterMiyagi

Reputation: 50076

While the lines of your posted code and error don't quite match, the issue is likely here:

    if data > current_node.data and data <= current_node.next.data:

While you check that current_node is not None, you never check that current_node.next isn't None either.

There are some other bugs, e.g. last_node is not defined, there is no concept for inserting at the front, and you always go through the entire list. This should work better:

def insertNode(data, first_node):
  current_node = first_node
  new_node = Node(data, current_node.next)
  if data <= current_node.data:
    # insert at start
    first_node = new_node
    new_node.next = first_node
  else:
    while current_node is not None:
      if current_node.next is None:
        # insert at end
        current_node.next = new_node
        break
      elif data > current_node.data and data <= current_node.next.data:
        # insert in-between current and next node
        new_node.next = current_node.next
        current_node.next = new_node
        break
      current_node = current_node.next
  print("Inserting node: " + str(data))
  return first_node  # must return first to avoid global variable!

To support changing first_node, you have to fill the list like this:

rand_num_iter = iter(random_nums)  # avoids making a copy in [1:]
first_node = Node(next(rand_num_iter), None)
for i in rand_num_iter:
  first_node = insertNode(i, first_node)

Upvotes: 1

Related Questions