如何在Python3中使用自定义比较函数?
在Python2.x中,我可以将自定义函数传递给sorted和.sort函数如何在Python3中使用自定义比较函数?,python,sorting,python-3.x,Python,Sorting,Python 3.x,在Python2.x中,我可以将自定义函数传递给sorted和.sort函数 >>> x=['kar','htar','har','ar'] >>> >>> sorted(x) ['ar', 'har', 'htar', 'kar'] >>> >>> sorted(x,cmp=customsort) ['kar', 'htar', 'har', 'ar'] 因为,在我的语言中,辅音是按这个顺序出现的 "
>>> x=['kar','htar','har','ar']
>>>
>>> sorted(x)
['ar', 'har', 'htar', 'kar']
>>>
>>> sorted(x,cmp=customsort)
['kar', 'htar', 'har', 'ar']
因为,在我的语言中,辅音是按这个顺序出现的
"k","kh",....,"ht",..."h",...,"a"
但是在python3.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
排序(x,cmp=customsort)
回溯(最近一次呼叫最后一次):
文件“”,第1行,在
TypeError:“cmp”是此函数的无效关键字参数
是否有其他选择,或者我是否也应该编写自己的排序函数
注:我使用“k”、“kh”等简化了。实际字符是Unicode,甚至更复杂,有时辅音前后都有元音,我做了自定义比较功能,所以这部分就可以了。唯一的问题是我无法将自定义比较函数传递给sorted或。sort使用
键
参数。它接受一个函数,该函数接受正在处理的值并返回一个值,该值提供用于排序的键
sorted(x, key=somekeyfunc)
使用
键
参数(并按照说明如何将旧的cmp
函数转换为键
函数)
functools
有一个在中提到的函数cmp\u to\u key
,而不是customsort(),您需要一个函数将每个单词翻译成Python已经知道如何排序的内容。例如,您可以将每个单词翻译成数字列表,其中每个数字表示字母表中每个字母出现的位置。大概是这样的:
my_alphabet = ['a', 'b', 'c']
def custom_key(word):
numbers = []
for letter in word:
numbers.append(my_alphabet.index(letter))
return numbers
x=['cbaba', 'ababa', 'bbaa']
x.sort(key=custom_key)
由于您的语言包含多个字符的字母,您的自定义_键功能显然需要更加复杂。这应该会给你一个大致的想法。我不知道这是否有帮助,但是你可以查看
区域设置模块。看起来您可以将区域设置为您的语言,并使用locale.strcoll
使用您的语言的排序规则来比较字符串。使用键
关键字并转换比较函数:
sorted(x, key=functools.cmp_to_key(customsort))
完整的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))
从functools导入cmp\u到\u键
nums=[28,50,17,12,121]
nums.sort(key=cmp_to_key(lambda x,y:1如果str(x)+str(y)
与普通对象排序相比:
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)
class NumStr:
定义初始值(self,v):
自我评价,自我评价
定义(自身、其他):
返回self.v+other.v
键只接受一个参数函数,cmp有两个参数,它们是不同的行为。我刚刚测试了,得到了一个错误,因为key关键字只传递一个参数,TypeError:customsort()正好接受两个位置参数(1个给定)
+1,看起来配方给了我一个解决方法,但我想我将失去一些性能,因为我将所有比较运算符=
传递给中间人,因为我最初的自定义排序是用C编写的,所以它的速度大约是默认排序的1/2倍。(只看了你的个人资料)你的公司正在阻止访问Google和StackOverflow?他们有多蠢?但是关于你的回答:我会对实际性能下降感兴趣。你能timeit
it吗?我做了一些基准测试,看起来比直接传递自定义C比较函数慢4倍左右。如果我需要一个键函数和一个cmp函数呢?我想按每个字典中的自定义键对字典列表进行排序sorted\u rows=sorted(rows,key=itemgetter('name'),cmp=locale.strxfrm)
gives TypeError:Python 3.2中,“cmp”是此函数的无效关键字参数:(functools在标准库中有一个cmp_to_键函数:谢谢+1,我认为这是ICU的方式。但由于我的语言没有分词器,也没有标准的罗马化规则,我认为这需要时间来研究。这对于流行语言来说是正确的,但我的语言没有操作系统、ICU和unicode.org的完全支持,所以这就是毫无疑问,但是+1是一个很好的建议。你试过排序(x)吗
?@SilentGhost,为了确保这一点,我只是再试了一次,当然不起作用,因为我的原始语言不在区域设置列表中,操作系统不支持排序。您可以将cmp包装为键函数。在HowToSorting站点搜索cmp\u To\u键。下面是类似的内容