Discussion:
How to sort this without 'cmp=' in python 3?
(too old to reply)
3***@gmail.com
2016-10-14 23:33:19 UTC
Permalink
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
Permalink
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
Permalink
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
Permalink
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
Permalink
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
Post by s***@gmail.com
Post by 3***@gmail.com
Post by 3***@gmail.com
result
'953432303'
Ben Finney
2016-10-14 23:59:01 UTC
Permalink
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
Type "help", "copyright", "credits" or "license" for more information.
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>

The `functools.cmp_to_key` helper is designed to help you transition to
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
Permalink
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
Permalink
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
!!!!!I learn more new tricks in Python. Thank you all of you guys.
You are all very kind helpful and knowledgeable.

Continue reading on narkive:
Loading...