28
我碰到过这个功能here。Python的cmp_to_key函数是如何工作的?
我对此感到困惑 - cmp_to_key
生成的key
函数如何知道给定元素应该是什么“位置”而不检查给定元素与其他每个感兴趣元素的比较方式?
我碰到过这个功能here。Python的cmp_to_key函数是如何工作的?
我对此感到困惑 - cmp_to_key
生成的key
函数如何知道给定元素应该是什么“位置”而不检查给定元素与其他每个感兴趣元素的比较方式?
的cmp_to_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')
排序时,每个键将得到相比于序列在大多数其他密钥。这个元素在位置0低于还是高于其他对象?
每当发生这种情况时,会调用特殊的方法钩子,因此调用__lt__
或__gt__
,代替键变为调用cmp
方法。
所以列表[1, 2, 3]
排序为[K(1), K(2), K(3)]
,并且如果说,K(1)
与K(2)
比较,看是否K(1)
较低,那么K(1).__lt__(K(2))
被调用,它被翻译成mycmp(1, 2) < 0
。
这就是旧的cmp
方法是如何工作的反正;返回-1,0或1,具体取决于第一个参数是否小于,等于或大于第二个参数。代理键将这些数字转换回比较运算符的布尔值。
代理键不需要知道任何关于的绝对位置。它只需要知道其他对象一个,而特殊的方法钩子提供了其他对象。
哇,一个实际的例子是Java对于相同的问题比Python有更简单的解决方案。没有太多。 – jeremyjjbrown 2014-08-26 13:54:59
@jeremyjjbrown:'cmp_to_key'函数仅用于支持传统的排序算法。简单的pythonic方法是对'sorted()'使用'key'函数。 – 2014-08-26 14:00:42
有时候想出一个'key'很难,但很容易想出一个比较函数......例如,我想对一个数字列表进行排序,以便所有奇数按照升序排列,然后全部接下来是偶数,按降序排列。 – rlbond 2015-07-17 00:42:41