Discussion:
How to sort this without 'cmp=' in python 3?
3***@gmail.com
2016-10-14 23:33:19 UTC
nums=['3','30','34','32','9','5']
I need to sort the list in order to get the largest number string: '953433230'

nums.sort(cmp=lambda a,b: cmp(a+b, b+a), reverse=True)

But how to do this in python 3?

Thank you
Robin Koch
2016-10-14 23:49:16 UTC
Post by 3***@gmail.com
nums=['3','30','34','32','9','5']
I need to sort the list in order to get the largest number string: '953433230'
nums.sort(cmp=lambda a,b: cmp(a+b, b+a), reverse=True)
But how to do this in python 3?
https://docs.python.org/3/library/functools.html#functools.cmp_to_key

| Transform an old-style comparison function to a key function.
--
Robin Koch
Ned Batchelder
2016-10-14 23:57:57 UTC
Post by Robin Koch
Post by 3***@gmail.com
nums=['3','30','34','32','9','5']
I need to sort the list in order to get the largest number string: '953433230'
nums.sort(cmp=lambda a,b: cmp(a+b, b+a), reverse=True)
But how to do this in python 3?
https://docs.python.org/3/library/functools.html#functools.cmp_to_key
| Transform an old-style comparison function to a key function.
cmp_to_key is a neat magic trick of a function, because it's seemingly
doing the impossible: how can a two-argument function be turned into
a one-argument function?

Studying the code turns up a few clever Python tricks.

--Ned.
s***@gmail.com
2016-10-14 23:53:37 UTC
Post by 3***@gmail.com
nums=['3','30','34','32','9','5']
I need to sort the list in order to get the largest number string: '953433230'
nums.sort(cmp=lambda a,b: cmp(a+b, b+a), reverse=True)
But how to do this in python 3?
Thank you
You don't need a lambda in this case.

Sort the strings in reverse order:
nums.sort(reverse=True)

Create a string:
biggestNum = ''.join(nums)

Or in a single line, which doesn't change the original value of nums:
biggestNum = ''.join(sorted(nums, reverse=True))
b***@gmail.com
2016-10-15 04:04:45 UTC
Post by s***@gmail.com
Post by 3***@gmail.com
nums=['3','30','34','32','9','5']
I need to sort the list in order to get the largest number string: '953433230'
nums.sort(cmp=lambda a,b: cmp(a+b, b+a), reverse=True)
But how to do this in python 3?
Thank you
You don't need a lambda in this case.
nums.sort(reverse=True)
biggestNum = ''.join(nums)
biggestNum = ''.join(sorted(nums, reverse=True))
No, you've made exactly the same mistake that I did :(
Post by s***@gmail.com
Post by 3***@gmail.com
Post by 3***@gmail.com
nums=['3','30','34','32','9','5']
wants='953433230'
nums.sort(reverse=True)
result = ''.join(nums)
result == wants
False
'953432303'
Ben Finney
2016-10-14 23:59:01 UTC
Post by 3***@gmail.com
nums=['3','30','34','32','9','5']
I need to sort the list in order to get the largest number string: '953433230'
nums.sort(cmp=lambda a,b: cmp(a+b, b+a), reverse=True)
For demonstration, I'll re-write this such that the names and output
make more sense::

\$ python2
Python 2.7.12+ (default, Sep 1 2016, 20:27:38)
[GCC 6.2.0 20160927] on linux2
Post by 3***@gmail.com
digits = ['3','30','34','32','9','5']
sorted(
... digits,
... cmp=(lambda a, b: cmp(a+b, b+a)),
... reverse=True)
['9', '5', '34', '3', '32', '30']
Post by 3***@gmail.com
But how to do this in python 3?
The Python 3 sorting functions take a ‘key’ parameter:

`key` specifies a function of one argument that is used to extract a
comparison key from each list element: `key=str.lower`. The default
value is `None` (compare the elements directly).

<URL:https://docs.python.org/3/library/functions.html#sorted>

that style:

functools.cmp_to_key(func)

Transform an old-style comparison function to a key function. Used
with tools that accept key functions (such as sorted(), min(),
max(), heapq.nlargest(), heapq.nsmallest(), itertools.groupby()).
This function is primarily used as a transition tool for programs
being converted from Python 2 which supported the use of comparison
functions.

A comparison function is any callable that accept two arguments,
compares them, and returns a negative number for less-than, zero for
equality, or a positive number for greater-than. A key function is a
callable that accepts one argument and returns another value to be
used as the sort key.

<URL:https://docs.python.org/3/library/functools.html#functools.cmp_to_key>

This works in the latest Python 2 and Python 3.
Post by 3***@gmail.com
import functools
digits = ['3','30','34','32','9','5']
sorted(
... digits,
... key=functools.cmp_to_key(lambda a, b: cmp(a+b, b+a)),
... reverse=True)
['9', '5', '34', '3', '32', '30']

The trick is done by creating a key function that takes an item for
comparison, and returns a custom object, which knows how to compare
itself as specified by your comparison function.
Post by 3***@gmail.com
key_func = functools.cmp_to_key(lambda a, b: cmp(a+b, b+a))
key_func("32")
<functools.K object at 0x7f6781ce0980>
Post by 3***@gmail.com
key_func("32") < key_func("5")
True

See the Sorting HOWTO <URL:https://docs.python.org/3/howto/sorting.html>
for this and other tricks.
--
\ “I used to be an airline pilot. I got fired because I kept |
`\ locking the keys in the plane. They caught me on an 80 foot |
_o__) stepladder with a coathanger.” —Steven Wright |
Ben Finney
Peter Otten
2016-10-15 07:26:51 UTC
Post by 3***@gmail.com
nums=['3','30','34','32','9','5']
I need to sort the list in order to get the largest number string: '953433230'
nums.sort(cmp=lambda a,b: cmp(a+b, b+a), reverse=True)
But how to do this in python 3?
Thank you
While cmp_to_key is neat doing it by hand should also be instructive.
Essentially you move the comparison into a method of the key:

\$ cat translate_cmp.py
class Key(str):
def __lt__(a, b):
return a + b < b + a

nums = ['3','30','34','32','9','5']
print(nums)
nums.sort(key=Key, reverse=True)
print(nums)
print("".join(nums))

\$ python3 translate_cmp.py
['3', '30', '34', '32', '9', '5']
['9', '5', '34', '3', '32', '30']
953433230

The above works because in CPython list.sort() currently uses only the <
operator; adding __gt__() and __eq__() to make this portable is
straightforward even if you do not use the functools.total_ordering class
decorator.
3***@gmail.com
2016-10-15 17:30:48 UTC