Python3列表理解无法按预期工作

时间:2018-10-25 10:11:37

标签: python list-comprehension

此刻,我正在用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表达式中缺少某些内容。那是什么?谢谢您的帮助。

1 个答案:

答案 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

进一步

  1. Python lambda's binding to local values