![](/img/trans.png)
[英]python groupby using comparator function/lambda instead of key function
[英]Can this comparator function be replaced with an equivalent key function?
假设我有一个比较器,它使用比较的两个值来决定排序。
例如,在这个问题中,我们必须使用一个使用两个元素的比较器函数:
def comparator(a, b):
ab = str(a) + str(b)
ba = str(b) + str(a)
return ((int(ba) > int(ab)) - (int(ba) < int(ab)))
排序时可以写成key=lambda x: ...
格式吗?
我知道有一个cmp_to_key
函数可以将cmp
函数转换为key
函数。 我的问题是我们是否可以将其编写为键函数而不必以这种方式进行转换。
由于您已经排除了像functools.cmp_to_key
一样工作的解决方案(即使用 dunder 比较方法声明一个类),我推断您想要一种方法来做到这一点,其中 key 函数仅使用内置类型。
问题是,从逻辑上讲,像 25 这样的数字的键是无限序列(2, 5, 2, 5, ...)
。 您需要无限序列的原因是您总是会遇到像 252525252525253 这样的数字,其中比较的结果取决于最后一位数字,因为其余数字是另一个数字的重复序列。
如果您对输入数字的大小有限制(假设我们知道它们最多为 10 位),那么序列只需要重复最多 10 位长度,然后进行字典比较(例如字符串或元组) 将工作:
def key_func(n, digits=10):
s = str(n)
return (s * digits)[:digits]
然而,正如 Stefan Pochmann 指出的那样,有一个内置类型Fraction
可用于表示无限重复的数字序列:例如, (2, 5, 2, 5, ...)
表示为Fraction(25, 99)
因为它的十进制扩展是0.2525...
。 比较分数相当于按字典顺序比较它们的十进制扩展:
from fractions import Fraction
def key_func(n):
k = len(str(n))
return Fraction(n, 10**k - 1)
示例(两个键功能相同):
>>> sorted([54, 546, 548, 60], key=key_func)
[54, 546, 548, 60]
>>> sorted([1, 34, 3, 98, 9, 76, 45, 4], key=key_func)
[1, 3, 34, 4, 45, 76, 98, 9]
>>> sorted([25, 252525251], key=key_func)
[252525251, 25]
>>> sorted([25, 252525253], key=key_func)
[25, 252525253]
结果列表应该以相反的顺序连接以通过连接产生最大可能的数字,因此例如[54, 546, 548, 60]
映射到6054854654
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.