我想更好地了解三个对象的交换在Python中是如何工作的。我对使用以下语法交换对象及其属性时顺序如何影响结果感到好奇。
left, right, right.attr = right, left.attr, right
特别是,我有以下代码要在其中反向链接列表:
class Solution(object):
def reverseList(self, head):
"""
:type head: ListNode
:rtype: ListNode
"""
if not head or not head.next:
return head
prev, cur = None, head
while cur:
cur, prev = swap(cur, prev)
return prev
我正在考虑两个swap
函数,每个函数以不同的顺序重新分配对象:
def swap_bad(cur, prev):
prev, cur, cur.next = cur, cur.next, prev
return cur, prev
和
def swap_good(cur, prev):
cur.next, cur, prev = prev, cur.next, cur
return cur, prev
我希望这两个功能是等效的,但是顾名思义,第一个功能不起作用,而第二个功能可以起作用。您能否阐明为什么会这样?
答案 0 :(得分:0)
这是Python执行命令顺序的一个示例。
设置如下:
class Test:
def __init__(self, name, nxt=None):
self.name = name
self.nxt = nxt
def __str__(self):
nxt = self.nxt.name if self.nxt is not None else None
return f"Test(name={self.name}, nxt={nxt})"
prev = Test(0)
cur = Test(1, prev)
def swap_good(cur, prev):
cur.nxt, cur, prev = prev, cur.nxt, cur
def swap_bad(cur, prev):
prev, cur, cur.nxt = cur, cur.nxt, prev
实际上,输出是不同的:
swap_good(cur, prev)
print(cur)
print(prev)
# Test(name=1, nxt=0)
# Test(name=0, nxt=None)
相对于
# re-initialize cur, prev as above
swap_bad(cur, prev)
print(cur)
print(prev)
# Test(name=1, nxt=0)
# Test(name=0, nxt=0) # nxt=0 instead of nxt=None
拆卸功能
from dis import dis
dis(swap_good)
dis(swap_bad)
为swap_good
20 0 LOAD_FAST 1 (prev)
2 LOAD_FAST 0 (cur)
4 LOAD_ATTR 0 (nxt)
6 LOAD_FAST 0 (cur)
8 ROT_THREE
10 ROT_TWO
12 LOAD_FAST 0 (cur)
14 STORE_ATTR 0 (nxt)
16 STORE_FAST 0 (cur)
18 STORE_FAST 1 (prev)
20 LOAD_CONST 0 (None)
22 RETURN_VALUE
和swap_bad
35 0 LOAD_FAST 0 (cur)
2 LOAD_FAST 0 (cur)
4 LOAD_ATTR 0 (nxt)
6 LOAD_FAST 1 (prev)
8 ROT_THREE
10 ROT_TWO
12 STORE_FAST 1 (prev)
14 STORE_FAST 0 (cur)
16 LOAD_FAST 0 (cur)
18 STORE_ATTR 0 (nxt)
20 LOAD_CONST 0 (None)
22 RETURN_VALUE
您可以看到不同之处(查找op-codes可以了解这里的实际情况;我很乐意这样做,但这应该可以帮助您入门)。