Reputation: 11170
I saw in a book how to pass a specific sorting function to Python's own built-in sorted() function as follows:
def mysort(a, b):
if a[3] < b[3]:
return -1
elif a[3] > b[3]:
return 1
else:
return 0
data = [
('Alpha Centauri A', 4.3, 0.26, 1.56),
('Alpha Centauri B', 4.3, 0.077, 0.45),
('Alpha Centauri C', 4.2, 0.00001, 0.00006),
("Barnard's Star", 6.0, 0.00004, 0.0005),
('Wolf 359', 7.7, 0.000001, 0.00002),
('BD +36 degrees 2147', 8.2, 0.0003, 0.006),
('Luyten 726-8 A', 8.4, 0.000003, 0.00006),
('Luyten 726-8 B', 8.4, 0.000002, 0.00004),
('Sirius A', 8.6, 1.00, 23.6),
('Sirius B', 8.6, 0.001, 0.003),
('Ross 154', 9.4, 0.00002, 0.0005),
]
sorted_data = sorted(data, mysort)
the code above sorts the data based on the 4th element of the 4-element tuple. Here, I am trying to figure out how the sorted() function feeds the a
and b
arguments to the mysort
function. My intention is passing another argument to the mysort
function similar to:
def mysort(a, b, i):
if a[i] < b[i]:
return -1
elif a[i] > b[i]:
return 1
else:
return 0
where it will tell the function which element should the sorting be based on. I am confused, because in the line
sorted_data = sorted(data, mysort)
we do not pass any arguments to the mysort
function. The sorted()
function seems to do its own magic, and provide the a
and b
arguments to the mysort
function. To summarize, I wonder if there is a way to add a 3rd argument to the mysort
function for different sorting types?
Thank you!
Upvotes: 0
Views: 1047
Reputation: 298146
You usually don't sort with cmp
(the second argument). The key
argument is the best choice 99% of the time:
def mysort(item):
return item[3]
sorted_data = sorted(data, key=mysort)
Or more concisely:
sorted_data = sorted(data, key=lambda item: item[3])
To make your second function work, you need to create a function with your function:
def mysort(i):
def sort_func(a, b)
if a[i] < b[i]:
return -1
elif a[i] > b[i]:
return 1
else:
return 0
return sort_func
And use it like:
sorted(data, mysort(3))
But a better way would be to use something builtin:
from operator imoprt itemgetter
sorted_data = sorted(data, key=itemgetter(3))
Upvotes: 3
Reputation: 1121594
You really want to use the key
argument instead; sorting on the 4th column with operator.itemgetter()
:
from operator import itemgetter
sorted(data, key=itemgetter(3))
or you could use a lambda
:
sorted(data, key=lambda elem: elem[3])
or you could use functools.partial()
:
from functools import partial
def mykeyfunc(column, item):
return item[column]
sorted(data, key=partial(mykeyfunc, 3))
All 3 options create a new callable that is passed each item in data
.
The cmp
argument to sorted()
has been removed in Python 3.
Upvotes: 5