我编写了以下函数用于使用 2 个参数进行线性回归(其背后的实际数学与这个问题无关)。它需要两个函数 ,f1
和f2
两个列表xs
, ys
:
def lr2par(f1, f2, xs, ys):
c11 = sum(map(lambda x: (f1(x))**2, xs))
c12 = sum(map(lambda x: f1(x) * f2(x), xs))
c22 = sum(map(lambda x: (f2(x))**2, xs))
d1 = sum(map(lambda x, y: y*f1(x), xs,ys))
d2 = sum(map(lambda x, y: y*f2(x), xs,ys))
a1 = -(c22*d1 - c12*d2)/(c12*c12 - c11*c22)
a2 = (c12*d1 - c11*d2)/(c12*c12 - c11*c22)
return (c11, c12, c22, d1, d2, a1, a2)
它按预期工作,xs
并且ys
是列表。但是,正如您所看到的,它是以一种非常实用的风格编写的,所以我当然希望能够在函数式代码中优雅地使用这个函数。这包括map
在将函数输入到函数之前调用列表中的函数,例如ys
本例中的参数:
lr2par(lambda x: x, lambda x: 1, [1, 3, 5, 7], map(math.log, [130, 150, 175, 210]))
这对我来说看起来很自然,我希望它能够工作(虽然我是一个 python 菜鸟)。事实证明它没有。我很确定问题是ys
参数现在不再是一个列表,而是一个迭代器(这似乎是使用 python 中的功能工具时的主要类型)只能迭代一次,所以当它涉及线
d2 = sum(map(lambda x, y: y*f2(x), xs,ys))
ys
只是空的。我想以一种惯用的函数式 Python 方式解决这个问题。我目前的解决方案是添加行
xs = list(xs)
ys = list(ys)
到函数体的开头。这行得通,但这是解决问题的好方法吗?我是否必须将这些行添加到几乎所有使用对象集合的函数中,并且可以很好地与 和 之类的函数map
一起filter
使用zip
?