在列表中交换两个元素会显示意外行为

时间:2017-07-02 03:48:01

标签: python arrays list python-3.x

我有一个清单:

lis = [12,45,15,67,89]

我想交换12和89,使列表看起来像

lis = [89,45,15,67,12]

当我这样做时

lis[0], lis[lis.index(89)] = lis[lis.index(89)], lis[0]

没有任何改变

lis = [12,45,15,67,89]

但是当我这样做的时候

lis5[0], lis5[4] = lis5[4], lis5[0]

完美无缺

lis = [89,45,15,67,12]

那为什么它不是第一种方式呢? PS-我想要做第一种方式的全部原因是因为我想在列表中找到max元素然后将它与列表的第一个元素交换。

类似的东西:

max1 = max(lis)
lis[0], lis[lis.index(max1)] = lis[lis.index(max1)], lis[0]

2 个答案:

答案 0 :(得分:7)

简而言之,左/右侧lis.index(max1)在不同时间进行评估;然后评估为不同的值(左侧为0,右侧为4

a, b = b, a

以上陈述:

  • 创建(b, a)元组
  • 将上面的元组解压缩到ab
    • a = old-value-of-b
    • b = old-value-of-a
lis[0], lis[lis.index(89)] = lis[lis.index(89)], lis[0]

变为

lis[0], lis[lis.index(89)] = lis[4], lis[0]

=>

lis[0], lis[lis.index(89)] = 89, 0

=>

lis[0] = 89
lis[lis.index(89)] = 0

=>

lis[0] = 89
lis[0] = 0    # NOTE lis.index(89) == 0  at this point

因此lis[0]分配了89,然后将原始值0分配回来。 => (仅更改了第一个元素,并重新分配了原始值)

要避免此问题,请在swap语句之前分配索引:

idx = lis.index(89)
lis[0], lis[idx] = lis[idx], lis[0]

答案 1 :(得分:1)

只是为了扩展接受的答案, 您可以使用 dict 进行存储。

lis = [12,45,15,67,89]
new_list = []


dict = {k:v for (k,v) in enumerate(lis)}

    
dict[0], dict[4] = dict[4], dict[0]
    
for i in range(len(lis)):
    new_list.append(dict[i])
   
print(new_list)

还有你尝试的方式,

lis = [12,45,15,67,89]

lis[lis.index(89)], lis[0] = lis[0], lis[lis.index(89)]

print(lis) 

两者都产生,

[89, 45, 15, 67, 12]

[Program finished]

或者,对于最大值,

lis = [12,45,15,67,89]
max_index = lis.index(max(lis))
lis[0], lis[max_index] = lis[max_index], lis[0]
print(lis)