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?
Answers:
Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.
Method 1
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.
Method 2
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.
Method 3
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)
Method 4
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)
Method 5
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
Method 6
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
All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0