Понимание списка Python3 не работает должным образом - PullRequest
0 голосов
/ 25 октября 2018

В настоящее время я использую лагранжевую форму интерполяционного полинома в Python.

Она состоит из суммы полиномов, с которых я начал.По заданному списку точек (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

как гласит теория.Естественно, я пытаюсь обобщить это, чтобы вычислить каждый многочлен компонента в список.Чтобы достичь этого, я окружаю лямбда-выражение другим пониманием списка, заменяя каждый случай индексированного доступа к 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.Я должен что-то упустить в списках или лямбда-выражениях.Что это такое?Заранее спасибо за помощь.

1 Ответ

0 голосов
/ 25 октября 2018

Проблема, с которой вы сталкиваетесь, известна как позднее закрытие привязки , в основном все функции работают с последним 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-лямбды к локальным значениям
...