Python 多个赋值抛出错误,但单独赋值不会

Python multiple assignment throws error but separate assignment does not

提问人:Raymond 提问时间:9/16/2019 最后编辑:Raymond 更新时间:9/16/2019 访问量:102

问:

我正在反转链表,但多个赋值会破坏此功能,而单独的赋值则不会。有人可以解释这两个代码部分之间的执行差异吗?

我知道表达式的右侧是在赋值之前计算的,但是据我所知,如果是这样的话,我无法访问 None.next。

class Node:
    def __init__(self, val=0, next=None):
        self.val = val
        self.next = next

def clear():
    print("------------------------------------------")

def isPalindrome(A):
    if A is None:
        return True

    # get length
    cur, length = A, 1
    while cur.next is not None:
        cur = cur.next
        length += 1

    # go to second half
    cur, index = A, 0
    while index < (length + 1) / 2:
        cur = cur.next
        index += 1


    # start reversing
    prev = None
    while cur is not None:
        # this throws error? what is the difference?
        # cur, prev, cur.next = cur.next, cur, prev
        temp = cur.next
        cur.next = prev
        prev = cur
        cur = temp

    # now prev has reversed second half
    secondHalf = prev
    firstHalf = A

    # traverse both halves, comparing Ll[n] with Ll[length - 1 - n]
    while secondHalf is not None and firstHalf is not None:
        if firstHalf.val != secondHalf.val:
            return False

        firstHalf = firstHalf.next
        secondHalf = secondHalf.next

    return True

# even length simple case
def isPalindromeTest():
    A = Node(1, Node(1, Node(1, Node(1))))

    clear()
    print(isPalindrome(A))

isPalindromeTest()

我期待评论的行

# cur, prev, cur.next = cur.next, cur, prev

等同于

temp = cur.next
cur.next = prev
prev = cur
cur = cur.next

如果我使用第一个代码部分,则会显示错误消息:

Traceback (most recent call last):
  File "linked_lists.py", line 1089, in <module>
    isPalindromeTest()
  File "linked_lists.py", line 1052, in isPalindromeTest
    print(isPalindrome(A))
  File "linked_lists.py", line 1027, in isPalindrome
    cur, prev, cur.next = cur.next, cur, prev
AttributeError: 'NoneType' object has no attribute 'next'

Implying that I am accessing None.next, which in this context it would have to be prev.next if anything?

第二个代码部分:

------------------------------------------
True

有人可以解释这两个代码部分之间的执行差异吗?

python-3.x 符优先级分配运算 执行顺序

评论

2赞 jasonharper 9/16/2019
如果你不打算使用它,那么分配给 的意义何在?最后一行是访问不正确的,因为已经重新分配了。 会在那里工作。tempcur.nextcur.nextcur = temp
0赞 Mateen Ulhaq 9/16/2019
它仍然抛出错误吗?(错误是什么?
0赞 Raymond 9/16/2019
edited,意味着末尾有 cur = temp
0赞 Raymond 9/16/2019
在问题中添加了错误消息

答:

0赞 Graham 9/16/2019 #1

我还发现这种行为令人惊讶,但一旦你考虑对象属性和执行顺序在这样的实例中如何工作,它就有意义了。

为了亲自演示它,我做了一个MCVE的例子:

class A:
    def __init__(self, a):
        self.a = a

a = A(1)
a, a.a = a.a, None

这些问题是,虽然一次评估了右侧,但左侧仍然是从左到右评估的。这意味着将重新分配给 perfectly,但到左侧被评估时,将不再具有 atribute,因为它已被重新分配给 int。aa.aa.aa.a

将最后一行替换为以下内容会产生相同的结果,并且可以更清楚地说明问题:

t = a.a, None
a = t[0]
a.a = t[1]

评论

0赞 Raymond 9/17/2019
谢谢,我没有考虑左边的分配顺序!