sorted 的关键参数是如何工作的?

How does the key argument to sorted work?

代码 1:

>>> sorted("This is a test string from Andrew".split(), key=str.lower)
    ['a', 'Andrew', 'from', 'is', 'string', 'test', 'This']

代码 2:

>>> student_tuples = [
...     ('john', 'A', 15),
...     ('jane', 'B', 12),
...     ('dave', 'B', 10),
... ]
>>> from operator import itemgetter, attrgetter
>>>
>>> sorted(student_tuples, key=itemgetter(2))
[('dave', 'B', 10), ('jane', 'B', 12), ('john', 'A', 15)]

为什么代码1中,key=str.lower中省略了(),加上括号报错,而代码2中key=itemgetter(2)中,括号却保留了?

稍微研究一下控制台 str.lower 引用 'str' 对象的方法 'lower' 和 str.lower() 是一个函数,但是 str.lower() 需要一个参数,所以正确地写成 str.lower("OH BOY") 并且它会 return oh boy 错误是因为你没有向函数传递任何参数,但它期待一个。

sortedkey 参数需要一个函数,然后 sorted 将其应用于要排序的事物的每个项目。 key(item) 的结果在排序过程中相互比较,而不是每个原始 item

你可以想象它是这样工作的:

def sorted(thing_to_sort, key):
    #
    # ... lots of complicated stuff ...
    #
            if key(x) < key(y):
                # do something
            else:
                # do something else
    #
    # ... lots more complicated stuff ...
    #
    return result

可以看到,括号()被添加到函数key里面sorted,应用到xy,它们是 thing_to_sort.

的项目

在您的第一个示例中,str.lower 是应用于每个 xy 的函数。

itemgetter有点不同。它是 return 另一个函数 的函数,在您的示例中,它是 另一个函数 应用于 xy.

您可以在控制台中看到 itemgetter 是如何工作的:

>>> from operator import itemgetter
>>> item = ('john', 'A', 15)
>>> func = itemgetter(2)
>>> func(item)
15

一开始可能有点难以理解 "higher order" 函数(接受或 return 其他函数的函数),但它们对很多不同的任务都非常有用,因此,值得尝试使用它们,直到您感到舒服为止。