What arguments does Python sort() function have?
Solution 1
Arguments of sort
and sorted
Both sort
and sorted
have three keyword arguments: cmp
, key
and reverse
.
L.sort(cmp=None, key=None, reverse=False) -- stable sort *IN PLACE*;
cmp(x, y) -> -1, 0, 1
sorted(iterable, cmp=None, key=None, reverse=False) --> new sorted list
Using key
and reverse
is preferred, because they work much faster than an equivalent cmp
.
key
should be a function which takes an item and returns a value to compare and sort by. reverse
allows to reverse sort order.
Using key
argument
You can use operator.itemgetter
as a key argument to sort by second, third etc. item in a tuple.
Example
>>> from operator import itemgetter
>>> a = range(5)
>>> b = a[::-1]
>>> c = map(lambda x: chr(((x+3)%5)+97), a)
>>> sequence = zip(a,b,c)
# sort by first item in a tuple
>>> sorted(sequence, key = itemgetter(0))
[(0, 4, 'd'), (1, 3, 'e'), (2, 2, 'a'), (3, 1, 'b'), (4, 0, 'c')]
# sort by second item in a tuple
>>> sorted(sequence, key = itemgetter(1))
[(4, 0, 'c'), (3, 1, 'b'), (2, 2, 'a'), (1, 3, 'e'), (0, 4, 'd')]
# sort by third item in a tuple
>>> sorted(sequence, key = itemgetter(2))
[(2, 2, 'a'), (3, 1, 'b'), (4, 0, 'c'), (0, 4, 'd'), (1, 3, 'e')]
Explanation
Sequences can contain any objects, not even comparable, but if we can define a function which produces something we can compare for each of the items, we can pass this function in key
argument to sort
or sorted
.
itemgetter
, in particular, creates such a function that fetches the given item from its operand. An example from its documentation:
After,
f=itemgetter(2)
, the callf(r)
returnsr[2]
.
Mini-benchmark, key
vs cmp
Just out of curiosity, key
and cmp
performance compared, smaller is better:
>>> from timeit import Timer
>>> Timer(stmt="sorted(xs,key=itemgetter(1))",setup="from operator import itemgetter;xs=range(100);xs=zip(xs,xs);").timeit(300000)
6.7079150676727295
>>> Timer(stmt="sorted(xs,key=lambda x:x[1])",setup="xs=range(100);xs=zip(xs,xs);").timeit(300000)
11.609490871429443
>>> Timer(stmt="sorted(xs,cmp=lambda a,b: cmp(a[1],b[1]))",setup="xs=range(100);xs=zip(xs,xs);").timeit(300000)
22.335839986801147
So, sorting with key
seems to be at least twice as fast as sorting with cmp
. Using itemgetter
instead of lambda x: x[1]
makes sort even faster.
Solution 2
Besides key=
, the sort
method of lists in Python 2.x could alternatively take a cmp=
argument (not a good idea, it's been removed in Python 3); with either or none of these two, you can always pass reverse=True
to have the sort go downwards (instead of upwards as is the default, and which you can also request explicitly with reverse=False
if you're really keen to do that for some reason). I have no idea what that value
argument you're mentioning is supposed to do.
Solution 3
Yes, it takes other arguments, but no value
.
>>> print list.sort.__doc__
L.sort(cmp=None, key=None, reverse=False) -- stable sort *IN PLACE*;
cmp(x, y) -> -1, 0, 1
What would a value
argument even mean?
zjm1126
Updated on April 25, 2020Comments
-
zjm1126 about 4 years
Is there any other argument than
key
, for example:value
? -
Admin over 14 years
help()
is generally more useful than printing__doc__
directly. -
sastanin over 14 yearsI usually use ipython, and there one can write just
list.sort?
instead ofhelp(list.sort)
to get help. -
Ishbir over 14 yearsHe just said "value" as an (out of place here) example because he's seen "key" and "value" mentioned together.
-
Mr_and_Mrs_D over 9 yearsHow can this work:
modNames.sort(key=lambda a: (a in data) and data.index(a))
(modNames, data are lists) ? -
Mr_and_Mrs_D almost 5 yearsWell, items in
modNames
that are indata
will be sorted as they are indata
- items that are not will be assigned key 0 and sorted in the beginning of the list along with the first item in data that also has key 0. -
Mr_and_Mrs_D almost 5 yearsOf note that
cmp
is deprecated in python3