Can this cmp function be better written as a key for sorted()?
Question: I was writing a solution to the problem of how to generate the maximum integer
by rearranging then concatenating integers from a set. I was given that for
the maximum integer, the arrangement of any two of its adjacent integers from
the set when expressed as an integer is greater than the arrangement of them
being swapped. i.e. given {98, 9}; the arrangement 998 is greater than 989.
This holds for all the constituent integers in the examples given below.

I needed to write some code that worked for Python 2.7 as well as 3.3 and came
up with the following Python code:

    
    
    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)))
    

This gives output:

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

Now Raymond Hettinger states that 'key=' is superior to 'cmp=' and I tend to
agree with him, (before his Pycon 2013 talk ["Transforming code into
Beautiful, Idiomatic Python"](https://www.youtube.com/watch?v=OSGv2VnC0go)).
My problem is that **I haven't been able to solve the problem with a key
function as elegant as the cmp function**.

Any ideas? Thanks.


Answer: There is a quite easy way (or i should say principle) to do it: You just have
to compare the mantissa of the numbers, e.g:

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

and so on…

How can you get that? Well, you have to get the length of the number `length =
log10(number)//1` and divide the number by `10**length`:

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

Now you can use the mantissa as key function:

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

So we just have to reverse the `sorted`-result and now we can use it just like
you did:

    
    
    >>> 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
    

