我正在编写一个列表排序函数,我正在尝试将列表的最小值与列表的第一个元素交换:
foo = [4, 7, 2, 9]
foo[0], foo[foo.index(min(foo))] = foo[foo.index(min(foo))], foo[0]
我期待结果:
foo = [2, 7, 4, 9]
但我得到了
foo = [4, 7, 2, 9]
没有任何改变。有什么帮助吗?
答案 0 :(得分:3)
让我们用一些临时变量来解决这个问题,看看发生了什么:
>>> foo = [4, 7, 2, 9]
>>> tup = foo[foo.index(min(foo))], foo[0]
>>> print tup
(2, 4)
>>> foo[0] = tup[0]
>>> print foo
[2, 7, 2, 9]
>>> dx = foo.index(min(foo))
>>> print dx
0
>>> foo[dx] = tup[1] # foo[dx] equivalent to foo[foo.index(min(foo))]
>>> print foo
[4, 7, 2, 9]
该作业具有将2
分配给foo[0]
的效果。然后将4
分配给foo
,在最小值的索引处计算为foo[0]
,因为您刚刚分配给它。
这是另一种通过记录评估顺序来看待它的方法:
foo[0], foo[foo.index(min(foo))] = foo[foo.index(min(foo))], foo[0]
1_______
2__________________
3_______________________ 4_____
5_______________________________
6_____
7_______
8__________________
9_______________________
1 find min
2 find index
3 get item by index
4 get item by index
5 make tuple
6 assign to foo at index 0 from left hand side of tuple from step 5)
7 find min
8 find index
9 assign to foo at index from step 8 from right hand side of tuple from step 5
答案 1 :(得分:1)
试试这个:
foo = [4, 7, 2, 9]
min_index=foo.index(min(foo))
foo[0], foo[min_index] = foo[min_index], foo[0]
输出:
[2, 7, 4, 9]
基本上,我认为索引在尝试交换之前和之后变得混乱,因此,没有任何事情发生。然而,如果您在开始尝试交换之前知道索引,那么交换就可以了。
答案 2 :(得分:1)
foo = [4, 7, 2, 9]
foo[foo.index(min(foo))], foo[0] = foo[0], foo[foo.index(min(foo))]
foo = [2, 7, 4, 9]
在重新分配foo[foo.index(min(foo))]
之后,似乎重新定义了等式左边的foo[0]
。交换订单时,不会发生这种重新定义。
答案 3 :(得分:0)
让我们看看发生了什么:
class ML(list): pass
def log(func):
def wrapped(*args,**kw):
rv = func(*args, **kw)
print rv
return rv
return wrapped
foo = ML(foo)
foo.index=log(foo.index)
>>> foo[0], foo[foo.index(min(foo))] = foo[foo.index(min(foo))], foo[0]
2
0
所以你的表达式等于
>>> foo[0], foo[0] = foo[2], foo[0]
>>> foo
[4, 7, 2, 9]
当您将foo[2]
的值分配给foo[0]
并将其还原为同一表达式时,操作将变为幂等。
为什么会这样?由于python首先评估表达式的正确部分,因此它发现foo[foo.index(min(foo))], foo[0]
是元组2, 4
。然后,它会从左侧将2
分配给foo[0]
,然后开始评估foo[foo.index(min(foo))]
。然后,它发现foo[0] = 2
foo.index(min(foo))
0
2
为foo[0]
,并将之前评估的值{{1}}分配给{{1}}。
答案 4 :(得分:0)
这一行:
foo[0], foo[foo.index(min(foo))] = foo[foo.index(min(foo))], foo[0]
将首先执行foo[0] = foo[foo.index(min(foo))]
,这将改变foo列表的第0个索引。然后它将执行foo[foo.index(min(foo))] = foo[0]
但foo[0]
已设置为分钟,因此index()
会在第0个位置找到它并分配它。基本上你是在尝试在原始列表上进行索引算术,但是你没有考虑到你在过渡期间改变它的状态。