Python sorted()键功能很奇怪

时间:2010-11-06 23:00:43

标签: python key sorted

当我调试一些不合逻辑的行为时,我在Python 2.5 sorted()函数调用中出现了以下奇怪现象:

>>> aa = [10, 5, 20]
>>> sorted(range(len(aa)))
[0, 1, 2]
sorted(range(len(aa)), key=lambda a: aa[a])
[1, 0, 2]
sorted(range(len(aa)), key=lambda a: -aa[a])
[2, 0, 1]

前两个电话按预期工作,但最后一个电话只是错误!它应该是:[1,2,0]。

经过进一步的实验尝试找到问题的根源后,我来到了这里(不使用lambda或者否定操作,但是否则是同样的问题):

>>> bb = [-10, -5, -20]
>>> sorted([0, 1, 2], key=bb.__getitem__)
[2, 0, 1]

即使像下面这样的事情也不起作用,并表明双重否定再次起作用:

>>> bb = [-10, -5, -20]
>>> def fun(i):
...    return bb[i]
>>> sorted([0, 1, 2], key=fun)
[2, 0, 1]
>>> def fun2(i):
...     return -bb[i]
>>> sorted([0, 1, 2], key=fun2)
[1, 0, 2]

我是在失去理智还是在哪里?或者为什么Python 3.x没有以前工作正常的 cmp 参数(兼容性是我不使用它的原因)?

3 个答案:

答案 0 :(得分:8)

key函数返回的值充当要排序的值的代理。 所以当你说

sorted(range(len(aa)), key=lambda a: -aa[a])

您正在排序range(len(aa)),即[0, 1, 2],但使用的是值 -aa[0], -aa[1], -aa[2]作为代理值。

range(len(aa))   0   1   2    <-- values
aa[a]           10   5  20
-aa[a]         -10  -5 -20    <-- proxy values

自-20或-aa[2]以来,是最小的代理值,其关联值为2 成为排序结果中的第一个元素。

从-10开始,或-aa[0]是下一个最小值,其关联值0成为排序结果中的第二个元素。

最后-5,或-aa[1]是最后一个值,因此1是排序结果中的最后一个数字。

因此,sorted(range(len(aa)), key=lambda a: -aa[a])等于[2, 0, 1]

Python给出的答案是正确的。

答案 1 :(得分:1)

  

最后一个是imho只是错误!它应该是:[1,2,0]

在第二个示例中,键是lambda a: aa[a],它为您提供按大小顺序递增的元素索引。

在最后一个示例中,密钥为lambda a: -aa[a]。由于否定,这为您提供减少大小顺序中元素的索引。

所以最后的结果应该是[2, 0, 1] - 它与[1, 0, 2]相反。

在这个例子中

>>> bb = [-10, -5, -20]
>>> sorted([0, 1, 2], key=bb.__getitem__)
[2, 0, 1]

您获得的元素索引按大小顺序递增 - [2, 0, 1]对应[-20, -10, -5]

在最后两个示例中,您将再次按大小顺序([2, 0, 1])或减小大小顺序([1, 0, 2])获取元素的索引。

答案 2 :(得分:0)

这对我来说很有意义

>>> bb = [-10, -5, -20]
>>> sorted([0, 1, 2], key=bb.__getitem__)
[2, 0, 1]  ==> corresponds to bb.__getitem__ of [-20, -10, -5]