如何在Python 3中使用自定义比较函数?

132 投票
6 回答
99271 浏览
提问于 2025-04-15 20:56

Python 2.x中,我可以把自己写的函数传给sorted和.sort这两个函数。

>>> x=['kar','htar','har','ar']
>>>
>>> sorted(x)
['ar', 'har', 'htar', 'kar']
>>> 
>>> sorted(x,cmp=customsort)
['kar', 'htar', 'har', 'ar']

因为在我的语言里,辅音的顺序是这样的。

"k","kh",....,"ht",..."h",...,"a"

但是在Python 3.x中,看起来我不能传cmp这个关键字了。

>>> sorted(x,cmp=customsort)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'cmp' is an invalid keyword argument for this function

有没有其他的办法,或者我也应该自己写一个排序函数呢?

注意:我用“k”、“kh”等简化了,实际的字符是Unicode,甚至更复杂,有时候辅音前后还会有元音。我已经写了自定义的比较函数,所以那部分没问题。唯一的问题是我不能把自定义的比较函数传给sorted或.sort。

6 个回答

26

这是一个完整的 Python3 中使用 cmp_to_key 的 lambda 示例:

from functools import cmp_to_key

nums = [28, 50, 17, 12, 121]
nums.sort(key=cmp_to_key(lambda x, y: 1 if str(x)+str(y) < str(y)+str(x) else -1))

接下来,我们来看看和普通对象排序的对比:

class NumStr:
    def __init__(self, v):
        self.v = v
    def __lt__(self, other):
        return self.v + other.v < other.v + self.v


A = [NumStr("12"), NumStr("121")]
A.sort()
print(A[0].v, A[1].v)

A = [obj.v for obj in A]
print(A)
77

使用 key 这个关键词,以及 functools.cmp_to_key 来转换你的比较函数:

sorted(x, key=functools.cmp_to_key(customsort))
64

使用 key 参数(并参考这个 教程,了解如何把你旧的 cmp 函数转换成 key 函数)。

functools 里有一个叫 cmp_to_key 的函数,具体可以查看 docs.python.org/3.6/library/functools.html#functools.cmp_to_key

撰写回答