Python 编写高阶归约,下面介绍相对复杂的高阶归约算法。最简单的归约形式是从集合数据中算出一个简单的标量值。Python内置了归约函数,包括any()
、all()
、max()
、min()
、sum()
和len()
。
前面可以使用简单的归约函数计算很多统计值,如下所示:
def s0(data: Sequence) -> float:
return sum(1 for x in data) # or len(data)
def s1(data: Sequence) -> float:
return sum(x for x in data) # or sum(data)
def s2(data: Sequence) -> float:
return sum(x * x for x in data)
使用几个简单的函数,就可以定义平均值、标准差、归一值、修正值甚至最小线性回归函数了。
上面最后一个简单归约s2()
展示了如何基于已有归约函数创建高阶函数,可如下所示改写实现方法:
from typing import Callable, Iterable, Any
def sum_f(
function: Callable[[Any], float],
data: Iterable) -> float:
return sum(function(x) for x in data)
其中有一个参数用于定义转换数据方法,计算结果是转换后的数值之和。
对于该函数有3种用法,可得到不同的和,如下所示:
N = sum_f(lambda x: 1, data) # x ** 0
S = sum_f(lambda x: x, data) # x ** 1
S2 = sum_f(lambda x: x * x, data) # x ** 2
使用简单的匿名函数,计算
,即序列长度
即序列和,以及
,序列元素平方和,然后就能计算出标准差了。
在此基础上,添加过滤器来扩展该算法,使其能去除序列中无效或者不希望保留的元素。去除无效数据如下所示:
def sum_filter_f(
filter_f: Callable,
function: Callable, data: Iterable) -> Iterator:
return sum(function(x) for x in data if filter_f(x))
执行以下命令可过滤掉None
值并计算序列和:
count_ = lambda x: 1
sum_ = lambda x: x
valid = lambda x: x is not None
N = sum_filter_f(valid, count_, data)
这段代码演示了sum_filter_f()
函数是如何使用两个匿名函数的。其中过滤器用于去除序列中的None
值,所以将其命名为valid
以体现其功能。function
参数是执行count
方法或者sum
方法的匿名函数,同理,计算平方和也很方便。
需要说明的是,该函数与其他高阶函数类似,返回的是一个函数,而不是一个值。这是高阶函数的一个核心特征,并且用Python易于实现。