Python 使用operator模块代替匿名函数,在使用max()
、min()
和sorted()
这些函数时,用到了一个可选的参数key=
。作为参数值的函数修改了高阶函数的行为。在许多情况下,可使用简单的匿名函数从元组中选取数据项,见以下两个典型示例:
from typing import Callable, Sequence, TypeVar
T_ = TypeVar("T_")
fst: Callable[[Sequence[T_]], T_] = lambda x: x[0]
snd: Callable[[Sequence[T_]], T_] = lambda x: x[1]
它们与其他一些函数式编程语言中的内置函数相匹配,用于选取元组的第一项或第二项。这里使用了类型提示来避免发生其他类型的转换,即把序列中项的类型绑定为类型变量T_
,以此表示函数返回结果的类型。
其实无须编写这样的函数,可以使用operator
模块中itemgetter()
的函数版本。它们都是高阶函数,即表达式itemgetter(0)
会创建一个函数。随后可以应用该函数来选取集合中的某个对象,如下所示:
>>> from operator import itemgetter
>>> itemgetter(0)([1, 2, 3])
1
下面在一个更复杂的元组列表数据结构中使用该函数。示例数据如下:
year_cheese = [
(2000, 29.87), (2001, 30.12), (2002, 30.6), (2003, 30.66),
(2004, 31.33), (2005, 32.62), (2006, 32.73), (2007, 33.5),
(2008, 32.84), (2009, 33.02), (2010, 32.92)
]
以上数据代表每年的奶酪消耗量。第2章和第9章用过这个示例。
可以使用以下命令来确定最小奶酪量的数据点:
>>> min(year_cheese, key=snd)
(2000, 29.87)
模块operator
提供了一种从元组中获取特定元素的替代方法。这使我们能免于使用匿名函数变量来选取其中第二项。
如以下命令所示,无须自定义fst()
函数和snd()
函数,而可以使用参数itemgetter(0)
和itemgetter(1)
。
>>> from operator import itemgetter
>>> max(year_cheese, key=itemgetter(1))
(2007, 33.5)
函数itemgetter()
依赖一个特殊方法__getitem__()
,它会根据数据项在元组(或列表)中的索引位置来获取其值。