Python sorted()键功能很奇怪

gw0*_*gw0 2 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]
Run Code Online (Sandbox Code Playgroud)

前两个调用按预期工作,但最后一个调用是错误的!它应该是:[1,2,0].

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

>>> bb = [-10, -5, -20]
>>> sorted([0, 1, 2], key=bb.__getitem__)
[2, 0, 1]
Run Code Online (Sandbox Code Playgroud)

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

>>> 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]
Run Code Online (Sandbox Code Playgroud)

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

unu*_*tbu 8

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

sorted(range(len(aa)), key=lambda a: -aa[a])
Run Code Online (Sandbox Code Playgroud)

你正在排序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
Run Code Online (Sandbox Code Playgroud)

从-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给出的答案是正确的.