l = [2,3,1,2,4,5]
l[0],l[l[0]] =l[l[0]],l[0]
print(l)
#wrong result?
l = [2,3,1,2,4,5]
l[l[0]],l[0] =l[0],l[l[0]]
print(l)
#correct result?
我被压死了〜
和第二个 之间的结果
l[0],l[l[0]] =l[l[0]],l[0]
和
l[0] = l[l[0]]
l[l[0]] = l[0]
结果也不同
答案 0 :(得分:2)
好吧,让我们抛开一个事实:您可能不应该做任何复杂的事情:-)
语句(a, b) = (c, d)
将值的元组分配给变量的元组,并且这些值是在 any 赋值之前计算的完成。
但是,对变量的分配是按顺序进行的,每个变量都是在不同的操作中计算并分配的。因此,请检查以下代码(希望使用b
代替a[something]
来使它更清晰):
>>> a = [0, 1] ; b = 0 ; (b, a[b]) = (1, 99) ; print(a)
[0, 99]
您得到[0, 99]
,因为将1
分配给b
的时间是 ,更重要的是,在找出99
实际引用的对象之前。
第二个赋值是给变量a[b]
而不是a[b]
,因为a[1 (= changed b)]
那时已经改变了。
如果您恢复使用列表元素而不是a[0 (= original b)]
,则会看到相同的效果:
b
唯一的区别是b
也已更改,因为那是您用于索引的对象,而不是>>> a = [0, 1] ; (a[0], a[a[0]]) = (1, 99) ; print(a)
[1, 99]
。
您的原因:
a[0]
代码段不起作用是因为它甚至还没有 close 成为交换对象。有效:
b
的结尾将是l[0] = l[l[0]]
l[l[0]] = l[0]
和a = b
b = a
both 都具有最初在a
中的值。更“ swappy”的版本将是:
b
,这对于使用b
的变体也适用,因为保证这三行中的每一行都在 下一行开始之前完全执行。
最重要的是,尽管元组分配是Python的一项非常强大的功能,但它确实有一些细微的边缘情况,可能会引起悲伤。假设您避免这些情况,仍然值得使用。