链表 while 语句(来自 LeetCode 的 addTwoNumbers)

linked list while statement (addTwoNumbers from LeetCode)

以下是我提交并随后被接受的代码。

class Solution(object):
def addTwoNumbers(self, l1, l2):
    """
    :type l1: ListNode
    :type l2: ListNode
    :rtype: ListNode
    """
    result = ListNode(0)
    result_tail = result
    carry = 0

    while l1 or l2 or carry:        

        val1  = (l1.val if l1.val else 0)
        val2  = (l2.val if l2.val else 0)

        out = (val1+val2 + carry)%10
        carry = (val1+val2 + carry)//10

        result_tail.next = ListNode(out)
        result_tail = result_tail.next                      

        l1 = (l1.next if l1.next else None)
        l2 = (l2.next if l2.next else None)

    return result.next 

最初,我有 while l1.val or l2.val or carry: 但它被拒绝并显示一条错误消息,内容如下:

AttributeError: 'NoneType' object has njo attribute 'val'

但是,链接节点列表 l1 和 l2 显然具有属性 val 和 next。

我不确定为什么 while l1.val or l2.val or carry: 不起作用。

下面是我最初提交但被拒绝的代码。

class Solution(object):
def addTwoNumbers(self, l1, l2):
    """
    :type l1: ListNode
    :type l2: ListNode
    :rtype: ListNode
    """
    result = ListNode(0)
    result_tail = result
    carry = 0

    print(l1.val)
    print(l2.val)
    while l1.val or l2.val or carry:        

        val1  = (l1.val if l1.val else 0)
        val2  = (l2.val if l2.val else 0)

        out = (val1+val2 + carry)%10
        carry = (val1+val2 + carry)//10

        result_tail.next = ListNode(out)
        result_tail = result_tail.next                      

        l1 = (l1.next if l1.next else None)
        l2 = (l2.next if l2.next else None)

    return result.next 

可能有一个测试用例,其中 l1 and/or l2 的传入值是 None。如果发生这种情况,则会引发 AttributeError,因为 None 没有任何此类属性 - 它只是 None(在其他语言中为 null)。

请注意,您通过简单地从 while 语句中的每个 l1 和 l2 中删除 .val 来解决检查 None 的问题。这就是为什么第二次提交被成功接受的原因。

因为 l1l2NoneType,或者本质上是 None,这意味着它们实际上 不是 你期望的类型。 None 是怎么进来的?嗯,两种方式之一:

首先,有人可以传入 None 作为输入 l1l2

第二个几乎可以肯定是您的问题,它来自以下语句:

        l1 = (l1.next if l1.next else None)
        l2 = (l2.next if l2.next else None)

换句话说,如果没有下一个值,我们将确保将其设置为 None。然后,因为我们在 l1 or l2 or carry 的条件下循环,所以其中只有一个必须是 "truthy"。换句话说,有可能 l1 是 None,并且 l2 是下一次迭代的有效列表,反之亦然......或者进位是真实的。或者两者兼而有之。

一个真相 table 为你的条件 l1 or l2 or carry 更好地形象化:

l1 | l2 | carry | result
------------------------
T---T----T------|   T
T---F----T------|   T
T---T----F------|   T
T---F----F------|   T
F---T----T------|   T
F---F----T------|   T
F---T----F------|   T
F---F----F------|   F

由于 None 是 "falsy" 类型,None 将计算为 False,但需要所有这三个条件为 False不继续循环。

至于一开始的打印,它们是before while 循环,所以每次迭代那个循环,l1l2得到一个不同的值。您已确保 传入 的内容不是 None。但这并没有阻止 l1l2 后来变成 None