Python 使用reduce()归约数据集,可以将sum()
、len()
、max()
和min()
函数看作reduce()
函数的特殊形式。reduce()
函数是高阶函数,能将可迭代对象中相邻的两个值通过指定函数结合在一起。
现有如下序列对象:
reduce()
函数对它应用+
运算符后效果如下:
为了更好地说明计算过程,给上面的表达式加上括号。
Python对表达式的标准解释方式是从左到右求值,所以与左卷积(fold-left)是同一个意思。有些函数式语言提供了右卷积(fold-right)函数,当与递归组合使用时,这些函数会进行优化处理。不过在Python中,归约都是从左到右进行的,所以不存在优化问题。
可以给归约提供一个初始值,如下所示:
如果不提供,则将序列的第一个值用作初始值。设置初始值的方式对于map()
函数和reduce()
函数都非常重要。下面通过设置初始值为0得到正确的计算结果:
如果不设置初始值,reduce()
函数使用序列的第一个值作为初始值,这个值就不会传递给卷积函数,导致计算错误。没有初始值的reduce()
函数的计算过程如下所示:
这样的错误告诉我们使用reduce()
函数时务必小心。
下面通过reduce()
高阶函数定义一些内置的归约函数。
其中sum2()
归约函数计算序列的平方和,在求样本集的标准差时很有用。sum()
归约函数模仿内置的sum()
函数的功能。count()
归约函数与len()
函数的功能类似,不过前者可以接收可迭代对象作为参数,而后者只能处理实例化的集合对象。
min()
函数和max()
函数模仿内置同名函数的功能。这里将序列第一个值作为初始值以保证计算结果正确。如果对reduce()
函数指定了额外的初始值,则会由于提供了一个序列中不存在的值而得到错误的结果。