表 14-6 中的函数都接受一个可迭代的对象,然后返回单个结果。这些函数叫“归约”函数、“合拢”函数或“累加”函数。其实,这里列出的每个内置函数都可以使用 functools.reduce 函数实现,内置是因为使用它们便于解决常见的问题。此外,对 allany 函数来说,有一项重要的优化措施是 reduce 函数做不到的:这两个函数会短路(即一旦确定了结果就立即停止使用迭代器)。参见示例 14-23 中 any 函数的最后一个测试。

表14-6:读取迭代器,返回单个值的内置函数

模块

函数

说明

(内置)

all(it)

it 中的所有元素都为真值时返回 True,否则返回 False;all([]) 返回 True

(内置)

any(it)

只要 it 中有元素为真值就返回 True,否则返回 False;any([]) 返回 False

(内置)

max(it, [key=,] [default=])

返回 it 中值最大的元素;*key 是排序函数,与 sorted 函数中的一样;如果可迭代的对象为空,返回 default

(内置)

min(it, [key=,] [default=])

返回 it 中值最小的元素;#key 是排序函数,与 sorted 函数中的一样;如果可迭代的对象为空,返回 default

functools

reduce(func, it, [initial])

把前两个元素传给 func,然后把计算结果和第三个元素传给 func,以此类推,返回最后的结果;如果提供了 initial,把它当作第一个元素传入

(内置)

sum(it, start=0)

it 中所有元素的总和,如果提供可选的 start,会把它加上(计算浮点数的加法时,可以使用 math.fsum 函数提高精度)

* 也可以像这样调用:max(arg1, arg2, ..., [key=?]),此时返回参数中的最大值。

# 也可以像这样调用:min(arg1, arg2, ..., [key=?]),此时返回参数中的最小值。

allany 函数的操作演示如示例 14-23 所示。

示例 14-23 把几个序列传给 allany 函数后得到的结果

>>> all([1, 2, 3])
True
>>> all([1, 0, 3])
False
>>> all([])
True
>>> any([1, 2, 3])
True
>>> any([1, 0, 3])
True
>>> any([0, 0.0])
False
>>> any([])
False
>>> g = (n for n in [0, 0.0, 7, 8])
>>> any(g)
True
>>> next(g)
8

10.6 节更为深入地解释过 functools.reduce 函数。

还有一个内置的函数接受一个可迭代的对象,返回不同的值——sortedreversed 是生成器函数,与此不同,sorted 会构建并返回真正的列表。毕竟,要读取输入的可迭代对象中的每一个元素才能排序,而且排序的对象是列表,因此 sorted 操作完成后返回排序后的列表。我在这里提到 sorted,是因为它可以处理任意的可迭代对象。

当然,sorted 和这些归约函数只能处理最终会停止的可迭代对象。否则,这些函数会一直收集元素,永远无法返回结果。

下面,我们回过头来分析内置的 iter() 函数,它还有一个鲜为人知的特性没有介绍。