当我调试一些不合逻辑的行为时,我在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 参数(兼容性是我不使用它的原因)?
答案 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]