python - 在 Python 中交换三个对象。为什么顺序相关?
问题描述
我想更好地了解三个对象的交换如何在 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
我希望这两个函数是等效的,但是正如名称所暗示的那样,第一个不起作用,而第二个起作用。你能解释一下为什么会这样吗?
解决方案
这是 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
您可以看到不同之处(查找操作码,您可以弄清楚这里到底发生了什么;诚然,我很懒惰这样做,但这应该可以帮助您入门)。
推荐阅读
- r - 如何将具有坐标列表(MultliLineString)的列转换为R上的sf/st对象?
- embedded - 覆盖 SD 分区布局的 WKS_FILE
- java - 如何从存储库访问和返回 AsyncTask 的结果?
- heroku - 如何在 HerokuApp 上访问 root 以使用 wget 命令
- android - 计费 API 3.0。价格变动用户通知
- flutter - 什么是 NoSuchMethod 错误,我该如何解决?
- visual-studio-code - VS Code + PHP Intelephense + Remote-SSH + Symfony 3:未定义的方法错误
- php - KNP Paginator 在 Symfony 5 中显示 Invalid item per page number 错误
- elasticsearch - 获取 Elasticsearch 中字段值与任何数组元素匹配的所有文档
- python - Pandas 按日期分组和计数。然后将计数转置为列名