简体   繁体   中英

Built-in sorted() function in Python

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!

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.

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))

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM