Python逗号分配顺序



我尝试Python逗号赋值来并行更改变量的值。我相信Python会先计算右侧表达式的值,然后将这些值分配给左侧的变量。一个具体的例子是在这个反向链表代码中:

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
class Solution:
def reverseList(self, head: ListNode) -> ListNode:
prev = None
curr = head
while curr != None:
prev, curr.next, curr = curr, prev, curr.next
return prev

prev, curr.next, curr = curr, prev, curr.next工作得非常好。如果我将订单更改为prev, curr, curr.next = curr, curr.next, prev,我希望我的代码也能正常工作:

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
class Solution:
def reverseList(self, head: ListNode) -> ListNode:
prev = None
curr = head
while curr != None:
prev, curr, curr.next = curr, curr.next, prev
return prev

然而,我在那行的第二个代码中得到了一个错误:

AttributeError: 'NoneType' object has no attribute 'next'
prev, curr, curr.next = curr, curr.next, prev

这对我来说没有意义,因为Python在赋值之前首先计算右侧表达式,这意味着我放置表达式的顺序应该无关紧要。我是不是遗漏了什么?

Python首先计算右侧是正确的;然而,缺少的是Python将按的顺序对的每一侧进行求值。我们可以通过将两个选项分解为单独的赋值语句来了解这意味着什么(Hastebin上的完整示例(:

# First example:
def reverseList(head: ListNode) -> ListNode:
prev = None
curr = head
while curr != None:
# prev, curr.next, curr = curr, prev, curr.next
x = curr
y = prev
z = curr.next
prev = x
curr.next = y
curr = z
return prev
# Second example:
def reverseList2(head: ListNode) -> ListNode:
prev = None
curr = head
while curr != None:
# prev, curr, curr.next = curr, curr.next, prev
x = curr
y = curr.next
z = prev
prev = x
curr = y
curr.next = z
return prev

这里的重要部分是,在第一个例子中,我们在分配curr的值之前分配curr.next的值,而在第二个例子中我们在之后分配curr.next的值。这意味着,当我们去分配curr.next时,我们已经更新了curr,所以当解释器再次访问curr.next进行另一个分配时,它将收回错误的引用。当您将curr设置为None,然后尝试访问curr.next以完成重新分配操作时,会发生错误。

请注意,尽量避免使用next作为变量名。由于它是一个内置函数,所以它可能会引起一些混乱,尽管它可能很好。

最新更新