Python列表的值未改变

3

我正在尝试解决一个问题。在试图改变列表值时,我观察到了奇怪的列表行为。我无法更改列表元素的值。

top = list(map(int, raw_input().split()))
staff = list(map(int, raw_input().split()))

ceo  = top[0]
coo = top[1]
cto = top[2]

top.extend(staff)
alls = sorted(top)
tot = len(alls)
print(alls)

alls[tot/2], alls[alls.index(ceo)] = alls[alls.index(ceo)], alls[tot/2]
print(alls)

alls[0], alls[alls.index(coo)] = alls[alls.index(coo)], alls[0]
alls[-1], alls[alls.index(cto)] = alls[alls.index(cto)], alls[-1]

print(alls)

这是程序的输出:
输入:
13 11 17
12 10

输出

[10, 11, 12, 13, 17]
[10, 11, 12, 13, 17]
[10, 11, 12, 13, 17]

所有列表值为什么都没有改变?我做错了什么吗?
编辑: 问题陈述:https://www.hackerearth.com/codejunk/algorithm/steal-the-show/ 我知道我的方法不是解决这个问题的最佳方式,但我想知道为什么列表值没有改变?

1
代码应该做什么? - Padraic Cunningham
这是一个正在进行的比赛的问题,所以无法提供链接。不过这重要吗? - Amit Tripathi
2
是的,这很重要,因为您只是倾倒了一堆没有解释实际发生和为什么发生的代码。 - Padraic Cunningham
1
你是不是想把员工排列一下,把CEO放在中间,其他两个人分别放在两端? - Padraic Cunningham
1
逻辑很简单,先对员工进行排序,然后将较小的COO和CTO放在开头,另一个放在结尾。唯一需要考虑的是当人数为偶数时,你有两个选择来安排CEO,你只需找到左右两侧差异更小的方案即可。 - Padraic Cunningham
显示剩余6条评论
1个回答

5
这里的问题在于您使用了错误的运算符组合。以第一个赋值为例进行分析:

问题出在运算符组合上。以第一个赋值为例进行解释:

alls[tot/2], alls[alls.index(ceo)] = alls[alls.index(ceo)], alls[tot/2]

会发生什么:

  1. 在开头,ceo 是 13,所以执行语句时 alls.index(ceo) 将是 3 ……但等等……这适用于赋值之前的时间。

  2. 首先将计算赋值之前的值。alls[alls.index(ceo)] 将是 13 ——难怪,因为 ceo 是 13。

  3. alls[tot/2] 将是 12,因为 tot/2 是 2(索引将是整数,所以逗号后面的部分将被忽略)。

  4. 于是右侧将得到 (13, 12)。

  5. 现在,进入赋值环节。首先将分配 alls[tot/2](但不能信任它,因为这是具体实现细节!)。

  6. 所以 alls[2] 将是 13!!

  7. 现在,是赋值的第二部分……alls.index(ceo) 将是 2……什么??

原因是,alls 目前包含 [10, 11, 13, 13, 17]……alls.index(ceo) 将被计算出并发现 13 在位置 2,然后才找到另一个在位置 3 的 13。

所以会发生什么——alls[2] 将被赋值为 12——列表又回到了先前的内容。

这是因为您使用组合运算符并始终评估子表达式而不考虑,子表达式将在评估过程中改变。

您可以通过将一些子表达式的结果分配给变量并使用它们来防止这种情况,而不是使表达式复杂化。 具体来说,可能在主要表达式内部更改的子表达式应在表达式之前计算并存储在变量中。


2
具体来说,在进行交换之前,计算指数 tot/2alls.index(ceo) 并将它们存储在变量中。(第二个是有问题的。) - Bill the Lizard
你是对的。我希望能清楚地表达出alls.index(ceo)是罪魁祸首。我想以一种适用于其他类似情况的方式来表述。tot/2在这里不是问题,因为tot在过程中不会改变。 - Juergen
是的,那更多是给楼主的留言。我知道你懂的。 ;) - Bill the Lizard
哦,我的错。我试图快速解决问题。谢谢!Juergen和Bill。 - Amit Tripathi
@BilltheLizard:不会有任何冒犯。我添加了一些句子,应该能让情况更清楚明白。 - Juergen

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接