python 3 中使用链表的三个(或更多)不同变量赋值的操作顺序
Order of operations for three (or more) distinct variable assignments using a linked list in python 3
我正在编写简单的代码来反转链表,并意识到赋值可以在一行上完成,我觉得这很酷:
def Reverse(head):
prev_node = None
curr_node = head
while curr_node:
prev_node, curr_node.next, curr_node = curr_node, prev_node, curr_node.next
return prev_node
但是我注意到,如果我颠倒 LHS 上的 curr_node.next(对应于 RHS 上的 prev_node)和 LHS 上的 curr_node 之间的分配顺序,代码将失败( ...curr_node.next 在 RHS 上)
def Reverse(head):
prev_node = None
curr_node = head
print(curr_node.data)
print(curr_node.next.data)
print(prev_node)
while curr_node:
prev_node, curr_node, curr_node.next = curr_node, curr_node.next, prev_node
return prev_node
输入是
1 2 3 4
输出为
1
2
None
但是 while 循环产生了以下错误(仅在第二个代码块上;第一个运行正常)
prev_node, curr_node, curr_node.next = curr_node, curr_node.next, prev_node
AttributeError: 'NoneType' object has no attribute 'next'
我能找到的关于该主题的最接近的讨论是 。这表示首先评估 RHS,从左到右。我认为这意味着 curr_node 被存储,然后是 prev_node,然后是 curr_node.next。然后分别赋值给prev_node、curr_node.next和curr_node。我看不出第一个和第二个例子之间的区别。我错过了一些简单的东西吗?
有谁知道为什么第一个示例运行而第二个示例产生错误?
是的,元组赋值首先计算右侧(从左到右),然后执行赋值,也从左到右。
来自Assignment statements documentation:
An assignment statement evaluates the expression list (remember that this can be a single expression or a comma-separated list, the latter yielding a tuple) and assigns the single resulting object to each of the target lists, from left to right.
在您的第二种情况下,您将 None
分配给 curr_node
,因此下一次分配给 curr_node.next
失败。
换句话说,这个有效:
prev_node, curr_node.next, curr_node = curr_node, None, None
(前提是 curr_node
在执行 curr_node.next = None
时仍然是具有 next
属性的 Node 实例),但是如果交换参数:
prev_node, curr_node, curr_node.next = curr_node, None, None
现在 curr_node = None
在 curr_node.next = prev_node
之前执行。
这是一个简化的演示,向您展示分配事项的顺序:
>>> class Node:
... next = None
...
>>> curr_node = Node()
>>> curr_node.next, curr_node = None, None # first attribute, then name
>>> curr_node = Node()
>>> curr_node, curr_node.next = None, None # first the name, no attribute anymore
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'NoneType' object has no attribute 'next'
我正在编写简单的代码来反转链表,并意识到赋值可以在一行上完成,我觉得这很酷:
def Reverse(head):
prev_node = None
curr_node = head
while curr_node:
prev_node, curr_node.next, curr_node = curr_node, prev_node, curr_node.next
return prev_node
但是我注意到,如果我颠倒 LHS 上的 curr_node.next(对应于 RHS 上的 prev_node)和 LHS 上的 curr_node 之间的分配顺序,代码将失败( ...curr_node.next 在 RHS 上)
def Reverse(head):
prev_node = None
curr_node = head
print(curr_node.data)
print(curr_node.next.data)
print(prev_node)
while curr_node:
prev_node, curr_node, curr_node.next = curr_node, curr_node.next, prev_node
return prev_node
输入是
1 2 3 4
输出为
1
2
None
但是 while 循环产生了以下错误(仅在第二个代码块上;第一个运行正常)
prev_node, curr_node, curr_node.next = curr_node, curr_node.next, prev_node
AttributeError: 'NoneType' object has no attribute 'next'
我能找到的关于该主题的最接近的讨论是
有谁知道为什么第一个示例运行而第二个示例产生错误?
是的,元组赋值首先计算右侧(从左到右),然后执行赋值,也从左到右。
来自Assignment statements documentation:
An assignment statement evaluates the expression list (remember that this can be a single expression or a comma-separated list, the latter yielding a tuple) and assigns the single resulting object to each of the target lists, from left to right.
在您的第二种情况下,您将 None
分配给 curr_node
,因此下一次分配给 curr_node.next
失败。
换句话说,这个有效:
prev_node, curr_node.next, curr_node = curr_node, None, None
(前提是 curr_node
在执行 curr_node.next = None
时仍然是具有 next
属性的 Node 实例),但是如果交换参数:
prev_node, curr_node, curr_node.next = curr_node, None, None
现在 curr_node = None
在 curr_node.next = prev_node
之前执行。
这是一个简化的演示,向您展示分配事项的顺序:
>>> class Node:
... next = None
...
>>> curr_node = Node()
>>> curr_node.next, curr_node = None, None # first attribute, then name
>>> curr_node = Node()
>>> curr_node, curr_node.next = None, None # first the name, no attribute anymore
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'NoneType' object has no attribute 'next'