我创建了一个简单的双向链表,带有一个追加方法和一个 str() ,它应该返回列表中存在的元素。 这是代码;
class Node:
def __init__(self,val):
self.next = None
self.prev = None
self.val = val
def __str__(self):
return self.val
class dll:
def __init__(self):
self.head = None
self.tail = None
self.length = 0
def append(self,val):
new = Node(val)
if not self.head:
self.head = new
self.tail = new
else:
new.prev = self.tail
self.tail.next = new
self.tail = new
self.length += 1
def __str__(self):
curr = self.head
res = str()
if not self.head:
return("Linked list is empty")
while curr:
res += str(curr.val) + ' <-> '
curr = curr.next
if curr.next is not None:
res += ' <-> '
return res
ll = dll()
print(ll)
ll.append(10)
ll.append(30)
print(ll)
当我执行此操作时,它返回“AttributeError:'NoneType'对象没有属性'next'”
我删除了条件
if curr.next is not None:
res += ' <-> '
而且它按预期工作,这很奇怪。 我以前创建过列表,但这种情况从未发生在我身上。 难道我做错了什么?预先感谢!
问题出在代码的这一部分:
curr = curr.next
if curr.next is not None:
res += ' <-> '
当
curr
引用链表中的last节点时,执行完curr = curr.next
后,curr
将是None
。但这使得 curr.next
成为无效的属性访问,这会产生您得到的错误。
你真正想要的是检查
curr
是否是最后一个节点,before向前移动。所以改变你的陈述顺序:
if curr.next is not None:
res += ' <-> '
curr = curr.next
这将解决问题。请注意,仅在循环体的
very端更改
curr
是有意义的,这样循环体中的其他所有内容都可以与 same curr
一起工作。
我建议更改您的
__str__
方法,以便每次创建一个新的更长的字符串时,它不会重复 +=
。使用 join
来达到这个目的更加Pythonic。我还会定义 __iter__
,然后在定义 __str__
时依赖它:
def __iter__(self):
curr = self.head
while curr:
yield curr.val
curr = curr.next
def __str__(self):
return " <-> ".join(map(str, self)) if self.head else "(empty)"
有了这个,你就可以做这样的事情:
print(ll)
print(*ll)
print(list(ll))
print(sum(ll))