How to sort this without 'cmp=' in python 3?

Ben Finney ben+python at benfinney.id.au
Fri Oct 14 19:59:01 EDT 2016


380162267qq at gmail.com writes:

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

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

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

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

    >>> key_func = functools.cmp_to_key(lambda a, b: cmp(a+b, b+a))
    >>> key_func("32")
    <functools.K object at 0x7f6781ce0980>
    >>> 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




More information about the Python-list mailing list