AttributeError:“NoneType”对象没有属性“next”;查了多篇文章都有同样的错误

问题描述 投票:0回答:1

我创建了一个简单的双向链表,带有一个追加方法和一个 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 += ' <-> '

而且它按预期工作,这很奇怪。 我以前创建过列表,但这种情况从未发生在我身上。 难道我做错了什么?预先感谢!

python python-3.x doubly-linked-list
1个回答
0
投票

问题出在代码的这一部分:

    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))
© www.soinside.com 2019 - 2024. All rights reserved.