此刻,我正在用Python进行插值多项式的Lagrange形式。
它由我开始的多项式之和组成。给定要拟合的点(x,y)的列表,我首先使用以下代码计算这些分量的多项式:
def f(x):
return x**2 - 1
def product(l):
from functools import reduce
return reduce(lambda x,y: x*y, l)
xs = [2,3,5]
ys = [f(x) for x in xs]
p0 = lambda x: product([(x - xj)/(xs[0] - xj) for xj in xs if xs[0] != xj])
到目前为止,一切正常,如下:
p0(2) = 1.0
p0(3) = 0.0
p0(5) = 0.0
如理论所说。我自然地尝试将其概括为将每个分量多项式计算为一个列表。为了实现这一点,我在lambda表达式周围加上了另一个列表理解,用xs
替换了对xi
的索引访问的所有出现,并在xi
上迭代xs
:>
p = [lambda x: product([(x - xj)/(xi - xj) for xj in xs if xi != xj]) for xi in xs]
看到此代码,我将非常有信心地同意,该列表的第一个元素与p0相同。但是,事实证明:
p[0](2) = 0.0
p[0](3) = 0.0
p[0](5) = 1.0
对p的所有元素同样成立。我必须在列表推导或lambda表达式中缺少某些内容。那是什么?谢谢您的帮助。
答案 0 :(得分:1)
您面临的问题称为late bind closure,基本上所有函数都与最后一个xi
一起使用,一种可能的解决方案是使用默认参数:
def f(x):
return x ** 2 - 1
def product(l):
from functools import reduce
return reduce(lambda x, y: x * y, l)
xs = [2, 3, 5]
ys = [f(x) for x in xs]
p0 = lambda x: product([(x - xj) / (xs[0] - xj) for xj in xs if xs[0] != xj])
p = [lambda x, xi=xi: product([(x - xj) / (xi - xj) for xj in xs if xi != xj]) for xi in xs]
print(p[0](2))
print(p[0](3))
print(p[0](5))
输出
1.0
0.0
0.0
进一步