为什么索引为0和1时不进行交换?

时间:2019-04-26 00:21:23

标签: python list indexing swap

我有一个由连续整数[1, 2, 3, ..., n]组成的无序数组,没有重复项。允许交换任何两个元素。我需要找到按升序对数组进行排序所需的最小交换次数。

从列表的第一个元素开始,我尝试将它们放置在正确的位置(例如,如果第一个元素为7,则应将其放在列表的第六个位置)。要在列表中一张一张地走,我要制作一份副本,然后在第二张列表中进行交换。

a = [4,3,1,2]
b = a[:]
swap = 0
for p in a:
  if (p!= b[p-1]):
    b[p-1], b[b.index(p)] =  b[b.index(p)], b[p-1]
    swap+=1
print(swap)

此代码有效,但在这种情况下,我必须交换列表中位置为0或1的两个元素。我不明白为什么?因为我没有超出限制。

有人可以向我解释为什么会这样吗?

例如,如果我打印p,则发生交换的两个索引,更新的b列表和更新的交换数量:

p = 4
idx1= 3 idx2= 0
b= [2, 3, 1, 4]
swap = 1
p = 3
idx1= 2 idx2= 1
b= [2, 1, 3, 4]
swap = 2
p = 1
idx1= 0 idx2= 1
b= [2, 1, 3, 4]
swap = 3
p = 2
idx1= 1 idx2= 0
b= [1, 2, 3, 4]
swap = 4

在这种情况下,您可以看到对于p = 1,当索引为0和1时,不会发生交换。

我更改了b [p-1],b [b.index(p)]的顺序,我不再遇到相同的问题,但我不明白原因。

1 个答案:

答案 0 :(得分:0)

我之前也遇到过同样的问题,并且停留了一段时间。造成这种情况的原因是多次分配的顺序。

b[p-1], b[b.index(p)] =  b[b.index(p)], b[p-1]

实际上,并非同时完全分配多个分配。打包和解包机制。因此它将首先更改b[p-1],并且在b.index(p)情况下,b[b.index(p)]中的p-1将找到一个新的索引p=1 idx1=0 idx2=1

如果您更改分配顺序,它将可以正常工作。

b[b.index(p)], b[p - 1] = b[p - 1], b[b.index(p)]

或首先计算idx:

idx1, idx2 = p - 1, b.index(p)
b[idx1], b[idx2] = b[idx2], b[idx1]

我建议使用第二个版本,因为第一个版本将执行两次index。费用是第二个版本的两倍。

您可以在此处参考我的相关问题:The mechanism behind mutiple assignment in Python


顺便说一句,我认为您的算法在这里效率不高,无法减少交换时间,但是请使用O(n)index操作,并在此处复制一个数组。我认为您可以使用相同的想法,只需交换原始数组即可。