Python值交换什么都不做

时间:2013-11-20 21:03:09

标签: python list swap

我正在编写一个列表排序函数,我正在尝试将列表的最小值与列表的第一个元素交换:

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]

没有任何改变。有什么帮助吗?

5 个答案:

答案 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 2foo[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个位置找到它并分配它。基本上你是在尝试在原始列表上进行索引算术,但是你没有考虑到你在过渡期间改变它的状态。