Python';s cmp_到_键功能是否正常?

Python';s cmp_到_键功能是否正常?,python,algorithm,sorting,cmp,python-internals,Python,Algorithm,Sorting,Cmp,Python Internals,我遇到了这个函数 我对如何实现这一点感到困惑——由cmp\u to\u key生成的key函数如何知道“位置”给定元素不应检查给定元素与其他所有感兴趣元素的比较情况。方法返回一个充当代理键的特殊对象: class K(object): __slots__ = ['obj'] def __init__(self, obj, *args): self.obj = obj def __lt__(self, other): return mycmp

我遇到了这个函数


我对如何实现这一点感到困惑——由
cmp\u to\u key
生成的
key
函数如何知道“位置”给定元素不应检查给定元素与其他所有感兴趣元素的比较情况。

方法返回一个充当代理键的特殊对象:

class K(object):
    __slots__ = ['obj']
    def __init__(self, obj, *args):
        self.obj = obj
    def __lt__(self, other):
        return mycmp(self.obj, other.obj) < 0
    def __gt__(self, other):
        return mycmp(self.obj, other.obj) > 0
    def __eq__(self, other):
        return mycmp(self.obj, other.obj) == 0
    def __le__(self, other):
        return mycmp(self.obj, other.obj) <= 0
    def __ge__(self, other):
        return mycmp(self.obj, other.obj) >= 0
    def __ne__(self, other):
        return mycmp(self.obj, other.obj) != 0
    def __hash__(self):
        raise TypeError('hash not implemented')
K类(对象):
__插槽\uuuj=['obj']
定义初始化(self,obj,*args):
self.obj=obj
定义(自身、其他):
返回mycmp(self.obj,other.obj)<0
定义(自身、其他):
返回mycmp(self.obj,other.obj)>0
定义(自身、其他):
返回mycmp(self.obj,other.obj)==0
定义(自我、其他):
返回mycmp(self.obj,other.obj)=0
定义(自身、其他):
返回mycmp(self.obj,other.obj)!=0
定义散列(自我):
raise TypeError('未实现哈希')
排序时,每个键将与序列中的大多数其他键进行比较。位置0处的此元素是否低于或大于另一个对象

每当发生这种情况时,都会调用特殊的方法挂钩,因此会调用
\uult\uuu
\ugt\uuuu
,而代理键会变成对
cmp
方法的调用

因此,列表
[1,2,3]
被排序为
[K(1),K(2),K(3)]
,如果,比如说,
K(1)
K(2)
进行比较,看看
K(1)
是否更低,然后调用
K(1)

这就是旧的
cmp
方法的工作原理;返回-1、0或1,具体取决于第一个参数是否小于、等于或大于第二个参数。代理键将这些数字转换回比较运算符的布尔值


代理键在任何时候都不需要知道任何关于绝对位置的信息。它只需要知道与之比较的另一个对象,而特殊的方法钩子提供了另一个对象。

@jeremyjjbrown:
cmp\u to\u键
函数的存在只是为了支持旧式Python 2排序代码库。更简单的pythonic方法是使用
key
函数代替
sorted()
,如果排序算法需要类似
cmp()
的方法,则直接实现自定义的富比较挂钩。有时很难找到
键,但很容易找到比较函数。。。e、 例如,我想对数字列表进行排序,使所有奇数以升序排列在第一位,然后所有偶数以降序排列在第二位。@rlbond返回一个元组,该元组的键为
(n%2==0,(n%2和1或-1)*n)
。我知道您可以为该问题生成一个键。但我可以很容易地想出一些更难的方法。@rlbond:然后创建定义自己顺序的对象;你可以用它们作为钥匙。这包括定义自己的富比较挂钩,就像
cmp\u to\u key()
使用的
K
类那样。