Custom Python list sorting

PythonListSorting

Python Problem Overview


I was refactoring some old code of mine and came across of this:

alist.sort(cmp_items)

def cmp_items(a, b):
    if a.foo > b.foo:
        return 1
    elif a.foo == b.foo:
        return 0
    else:
        return -1

The code works (and I wrote it some 3 years ago!) but I cannot find this thing documented anywhere in the Python docs and everybody uses sorted() to implement custom sorting. Can someone explain why this works?

Python Solutions


Solution 1 - Python

As a side note, here is a better alternative to implement the same sorting:

alist.sort(key=lambda x: x.foo)

Or alternatively:

import operator
alist.sort(key=operator.attrgetter('foo'))

Check out the Sorting How To, it is very useful.

Solution 2 - Python

It's documented here.

> The sort() method takes optional arguments for controlling the > comparisons. > > cmp specifies a custom comparison function of two arguments (list > items) which should return a negative, zero or positive number > depending on whether the first argument is considered smaller than, > equal to, or larger than the second argument: cmp=lambda x,y: > cmp(x.lower(), y.lower()). The default value is None.

Solution 3 - Python

Just like this example. You want sort this list.

[('c', 2), ('b', 2), ('a', 3)]

output:

[('a', 3), ('b', 2), ('c', 2)]

you should sort the tuples by the second item, then the first:

def letter_cmp(a, b):
    if a[1] > b[1]:
        return -1
    elif a[1] == b[1]:
        if a[0] > b[0]:
            return 1
        else:
            return -1
    else:
        return 1

Then convert it to a key function:

from functools import cmp_to_key
letter_cmp_key = cmp_to_key(letter_cmp))

Now you can use your custom sort order:

[('c', 2), ('b', 2), ('a', 3)].sort(key=letter_cmp_key)

Solution 4 - Python

This does not work in Python 3.

You can use functools cmp_to_key to have old-style comparison functions work though.

from functools import cmp_to_key

def cmp_items(a, b):
    if a.foo > b.foo:
        return 1
    elif a.foo == b.foo:
        return 0
    else:
        return -1

cmp_items_py3 = cmp_to_key(cmp_items)

alist.sort(cmp_items_py3)

Solution 5 - Python

I know many have already posted some good answers. However I want to suggest one nice and easy method without importing any library.

l = [(2, 3), (3, 4), (2, 4)]
l.sort(key = lambda x: (-x[0], -x[1]) )
print(l)
l.sort(key = lambda x: (x[0], -x[1]) )
print(l)

Output will be

[(3, 4), (2, 4), (2, 3)]
[(2, 4), (2, 3), (3, 4)]

The output will be sorted based on the order of the parameters we provided in the tuple format

Solution 6 - Python

Even better:

student_tuples = [    ('john', 'A', 15),    ('jane', 'B', 12),    ('dave', 'B', 10),]

sorted(student_tuples, key=lambda student: student[2])   # sort by age
[('dave', 'B', 10), ('jane', 'B', 12), ('john', 'A', 15)]

Taken from: https://docs.python.org/3/howto/sorting.html

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionLorenzoView Question on Stackoverflow
Solution 1 - PythonAndrew ClarkView Answer on Stackoverflow
Solution 2 - Pythonmiles82View Answer on Stackoverflow
Solution 3 - PythonRryLeeView Answer on Stackoverflow
Solution 4 - PythonThe Unfun CatView Answer on Stackoverflow
Solution 5 - PythonpeddiashrithView Answer on Stackoverflow
Solution 6 - PythonStevenView Answer on Stackoverflow