[python] Custom Python list sorting

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?

This question is related to python list sorting

The answer is


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)

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.


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)

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


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


Examples related to python

programming a servo thru a barometer Is there a way to view two blocks of code from the same file simultaneously in Sublime Text? python variable NameError Why my regexp for hyphenated words doesn't work? Comparing a variable with a string python not working when redirecting from bash script is it possible to add colors to python output? Get Public URL for File - Google Cloud Storage - App Engine (Python) Real time face detection OpenCV, Python xlrd.biffh.XLRDError: Excel xlsx file; not supported Could not load dynamic library 'cudart64_101.dll' on tensorflow CPU-only installation

Examples related to list

Convert List to Pandas Dataframe Column Python find elements in one list that are not in the other Sorting a list with stream.sorted() in Java Python Loop: List Index Out of Range How to combine two lists in R How do I multiply each element in a list by a number? Save a list to a .txt file The most efficient way to remove first N elements in a list? TypeError: list indices must be integers or slices, not str Parse JSON String into List<string>

Examples related to sorting

Sort Array of object by object field in Angular 6 Sorting a list with stream.sorted() in Java How to sort dates from Oldest to Newest in Excel? how to sort pandas dataframe from one column Reverse a comparator in Java 8 Find the unique values in a column and then sort them pandas groupby sort within groups pandas groupby sort descending order Efficiently sorting a numpy array in descending order? Swift: Sort array of objects alphabetically