Python就地交换
以下代码块不起作用。
a = [2,1,3]
i = 1
a[i], a[a[i]-1] = a[a[i]-1], a[i]
而这样做。
a = [2,1,3]
i = 1
j = a[i]-1
a[i], a[j] = a[j], a[i]
有人知道吗?
回答
等号的左侧是从左到右分配的,并且每个术语仅在达到时才进行评估。这意味着:
a[i], a[a[i]-1] = a[a[i]-1], a[i]
相当于:
tmp = a[a[i]-1], a[i]
a[i] = tmp[0] # Changes a[i]
a[a[i]-1] = tmp[1] # USES new a[i] to determine assignment index!!!
这清楚地表明分配到a[i]
完成,然后使用的新值a[i]
来计算第二个分配的索引。
您的工作代码之所以有效,是因为它缓存了 的旧值a[i]
,因此重新分配a[i]
不会改变第二个值的位置;那里的等效代码清楚地说明了这一点:
j = a[i]-1 # Caches old a[i]
tmp = a[j], a[i]
a[i] = tmp[0] # Changes a[i]
a[j] = tmp[1] # Changes using original a[i] as intended