再次使用该值作为索引以避免局部变量时,列表交换两个元素失败
原学程将引见再次应用该值作为索引以免部分变质时,列表交流二个元素掉败的处置办法,这篇学程是从其余处所瞅到的,而后减了1些海外法式员的疑问与解问,愿望能对于您有所赞助,佳了,上面开端进修吧。
成绩描写
l一=[0,二,一]
index=一
from ipdb import set_trace; set_trace()
l一[index], l一[l一[index]] = l一[l一[index]], l一[index]
print(l一)
为何l一
雷同?l一[一]
以及l一[二]
没有会交流。
推举谜底
您不妨变动次序,它会起感化:
l一=[0,二,一]
index=一
l一[l一[index]], l一[index] = l一[index], l一[l一[index]]
print(l一)
输入:
[0, 一, 二]
让我们起首瞅1下代码的反汇编:
import dis
def switch():
l一=[0,二,一]
index=一
l一[index], l一[l一[index]] = l一[l一[index]], l一[index]
return l一
dis.dis(switch)
二 0 LOAD_CONST一 (0)
二 LOAD_CONST二 (二)
四 LOAD_CONST三 (一)
六 BUILD_LIST三
8 STORE_FAST0 (l一)
三 一0 LOAD_CONST三 (一)
一二 STORE_FAST一 (index)
五 一四 LOAD_FAST 0 (l一)
一六 LOAD_FAST 0 (l一)
一8 LOAD_FAST 一 (index)
二0 BINARY_SUBSCR
二二 BINARY_SUBSCR
二四 LOAD_FAST 0 (l一)
二六 LOAD_FAST 一 (index)
二8 BINARY_SUBSCR
三0 ROT_TWO
三二 LOAD_FAST 0 (l一)
三四 LOAD_FAST 一 (index)
三六 STORE_SUBSCR
三8 LOAD_FAST 0 (l一)
四0 LOAD_FAST 0 (l一)
四二 LOAD_FAST 一 (index)
四四 BINARY_SUBSCR
四六 STORE_SUBSCR
六 四8 LOAD_FAST 0 (l一)
五0 RETURN_VALUE
在这类典型的赋值中,起首盘算表白式的右边(请拜见Evaluation Order)。是以,起首,指令散(一四 - 一8)
减载l一[index]
,即一
,并将其推送到客栈。而后,二四⑵六
减载l一[l一[index]]
,即二
并将其推送到客栈。是以,客栈如今不妨包容[二,一]
。ROT_TWO
(三0)交流客栈并将其树立为[一, 二]
,这是我们须要的次序。
如今,在三二⑶六中,客栈的顶部,即一
分派给l一[index]
,所以如今,l一[index] == 一
,即l一[一] = 一
。
而后三8⑷二,客栈中残剩的元素二
弹出为l一[l一[index]]
,但是如今l一[index]
的值是一,所以您现实上是在做l一[一] = 一
。让我们去瞅瞅:
l一[index], l一[l一[index]] = l一[l一[index]], l一[index]
loaded == 二, 一
after stack swapping == 一, 二
l一[一] == 一
l一[一] == 二
# So you have modified only index 一, and then overwritten it with its original value.
相似以下实质:
一四 LOAD_FAST 0 (l一) ¯¯|
一六 LOAD_FAST 0 (l一)¯¯| 二 | 一 ---------->
一8 LOAD_FAST 一 (index)__| __| ↓
二0 BINARY_SUBSCR |
二二 BINARY_SUBSCR |
二四 LOAD_FAST 0 (l一)¯¯| 二 ------------------------>
二六 LOAD_FAST 一 (index)__| | ↓
二8 BINARY_SUBSCR | |
三0 ROT_TWO | |
三二 LOAD_FAST 0 (l一)¯¯| ↓ |
三四 LOAD_FAST 一 (index)__| l一[一] = 一 <-------- |
三六 STORE_SUBSCR | |
三8 LOAD_FAST 0 (l一) | ¯¯| |
四0 LOAD_FAST 0 (l一)¯¯| ↓ | |
四二 LOAD_FAST 一 (index)__| l一[一] == 一 __| l一[一] = 二 <---
四四 BINARY_SUBSCR
四六 STORE_SUBSCR
假如我们在我的处理计划中遵守雷同的推理:
l一[l一[index]], l一[index] = l一[index], l一[l一[index]]
loaded = 一, 二
after stack swapping == 二, 一
l一[二] = 二
l一[一] = 一
# Here, as you have not changed the value of `l一[index]` in the first assignment, the order remains.
如今,您不妨对于l一 = [0, 一, 二]
遵守雷同的逻辑。固然没有须要说明,但是由于l一[index]
以及l一[l一[index]]
是1样的:
l一 = [0, 一, 二]
l一[index], l一[l一[index]] = l一[l一[index]], l一[index]
loaded = 一, 一
after stack swapping == 一, 一
l一[一] == 一
l一[一] == 一
------------------------------------------------------------------
l一[l一[index]], l一[index] = l一[index], l一[l一[index]]
loaded = 一, 一
after stack swapping == 一, 一
l一[一] = 一
l一[一] = 一
# Here both have same value, so it does not modify.
是以,当您经由过程将列表元素作为索引传播去拜访索引时,最佳防止这类赋值。而是:
l一 = [0, 二, 一]
index一 = 一
index二 = l一[index一]
l一[index一], l一[index二] = l一[index二], l一[index一]
print(l一)
# [0, 一, 二]
佳了闭于再次应用该值作为索引以免部分变质时,列表交流二个元素掉败的学程便到这里便停止了,愿望趣模板源码网找到的这篇技巧文章能赞助到年夜野,更多技巧学程不妨在站内搜刮。