Я попытался создать простой односвязный список следующим образом:
class node:
def __init__(self, data=None):
self.data = data
self.next = None
class linkedlist:
def __init__(self):
self.head = node()
def append(self, data):
curr = self.head
new_node = node(data)
while curr.next != None:
curr = curr.next
curr.next = new_node
def total(self):
curr = self.head
total = 0
while curr.next != None:
curr = curr.next
total += 1
return total
def display(self):
# added total here as well
curr = self.head
em = []
total = 0
while curr.next != None:
curr = curr.next
em.append(curr.data)
total += 1
print(f"LinkedList: {em} \n Total: {self.total()} ")
def look(self, index):
if index >= self.total():
print("ERROR: Index error" )
curr_index = self.head
idx = 0
while True:
curr_index = curr_index.next
if idx == index:
print(curr_index.data)
idx += 1
Всякий раз, когда я вызываю функцию look()
, я получаю следующую ошибку:
curr_index = curr_index.next
^^^^^^^^^^^^^^^
AttributeError: 'NoneType' object has no attribute 'next'
Что это может означать?
Насколько я знаю, curr_index
использует self.head
, который, в свою очередь, использует node()
. У node()
есть атрибут next
.
Этой ошибки нет, когда я вызываю другие функции класса. Более того, другие функции, за исключением функции look()
, возвращают соответствующие значения без ошибок.
Где мой код идет не так?
Измените его на пока while curr_index.next:
«Что это может означать?»: это означает, что curr_index
есть None
и None
не имеет атрибута next
.
В этой реализации каждый узел указывает на следующий узел списка, а последний указывает на None
, что означает конец списка.
Цикл в look
пытается перебирать узлы, пока не дойдет до index
-го элемента, а затем печатает его, но на этом цикл не завершается. Фактически, он будет продолжаться бесконечно, пока в какой-то момент не пройдет последний элемент, создав текущий элемент None
, а затем произойдет сбой с этой ошибкой.
Один из подходов — явно завершить цикл, как только вы достигнете нужного элемента:
def look(self, index):
if index >= self.total():
# Need to throw here, not just print
# because printing out an error won't prevent the function from moving on
throw ValueError("ERROR: Index error")
curr_index = self.head
idx = 0
while True:
curr_index = curr_index.next
if idx == index:
print(curr_index.data)
return # We're done here, return
idx += 1
При этом проверка idx == index
на каждой итерации является излишней. Вы можете просто заранее curr_index
index
раз явно указать:
def look(self, index):
if index >= self.total():
# Need to throw here, not just print
# because printing out an error won't prevent the function from moving on
throw ValueError("ERROR: Index error")
curr_index = self.head
for _ in range(index):
curr_index = curr_index.next
print(curr_index.data)
Ошибка в этом коде возникает из-за того, что вы указали метод while True
внутри look()
, в котором цикл будет бесконечным, поэтому он обращается к указателю next
узла, которого нет в связанном списке, поэтому отображается ошибка.
Решение :-
# Change while True: to while curr_index:
def look(self, index):
if index >= self.total():
print("ERROR: Index error" )
curr_index = self.head
idx = 0
while curr_index:
curr_index = curr_index.next
if idx == index:
print(curr_index.data)
idx += 1
Я надеюсь, что это было полезно для вас.
while True:
Цикл бесконечен