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