这个cmp函数可以更好地写为sorted()的键吗?

时间:2013-04-03 20:11:40

标签: python sorting cmp

我正在编写一个解决方案,解决如何通过重新排列然后连接集合中的整数来生成最大整数的问题。我得到的是,对于最大整数,当表示为整数时,来自集合的任何两个相邻整数的排列大于它们被交换的排列。即{98,9};排列998大于989.这适用于下面给出的例子中的所有组成整数。

我需要编写一些适用于Python 2.7和3.3的代码,并提出以下Python代码:

try:
    cmp     # Python 2 OK or NameError in Python 3
    def maxnum(x):
        return ''.join(sorted((str(n) for n in x),
                              cmp=lambda x,y:cmp(int(y+x), int(x+y))))
except NameError:
    # Python 3
    from functools import cmp_to_key
    def cmp(x, y):
        return -1 if x<y else ( 0 if x==y else 1)
    def maxnum(x):
        return ''.join(sorted((str(n) for n in x),
                              key=cmp_to_key(lambda x,y:cmp(int(y+x), int(x+y)))))

for numbers in [(1, 34, 3, 98, 9, 76, 45, 4), (54, 546, 548, 60)]:
    print('Numbers: %r\n  Largest integer: %15s' % (numbers, maxnum(numbers)))

这给出了输出:

Numbers: (1, 34, 3, 98, 9, 76, 45, 4)
  Largest integer:    998764543431
Numbers: (54, 546, 548, 60)
  Largest integer:      6054854654

现在Raymond Hettinger表示'key ='优于'cmp ='而且我倾向于同意他,(在他2013年的Pycon谈话"Transforming code into Beautiful, Idiomatic Python"之前)。 我的问题是我无法通过像cmp函数那样优雅的关键功能解决问题

有什么想法吗?感谢。

1 个答案:

答案 0 :(得分:0)

有一种非常简单的方法(或者我应该说是原则):你只需要比较数字的尾数,例如:

1 -> 1.0
34 -> 3.4
548 -> 5.48

依旧......

你怎么能得到它?好吧,你必须得到数字length = log10(number)//1的长度并将数字除以10**length

from math import log10
def mantissa(number):
    return number / 10**( log10(number)//1 )

现在您可以使用尾数作为关键功能:

>>> sorted((1, 34, 3, 98, 9, 76, 45, 4), key = mantissa )
[1, 3, 34, 4, 45, 76, 9, 98]

所以我们只需要反转sorted - 结果,现在我们可以像你一样使用它:

>>> for numbers in [(1, 34, 3, 98, 9, 76, 45, 4), (54, 546, 548, 60)]:
...     print 'Numbers: %r\n  Largest integer: %15s' % (
                numbers,
                ''.join(str(i) for i in sorted(numbers, key = mantissa, reverse = True))
               )
... 
Numbers: (1, 34, 3, 98, 9, 76, 45, 4)
  Largest integer:    989764543431
Numbers: (54, 546, 548, 60)
  Largest integer:      6054854654