Форум сайта python.su
Создаю список функций вычисляющих многочлен Лежандра от нулевого до пятого порядка при заданном x.
from scipy.special import eval_legendre M0 = 6 f0_l = [lambda x: eval_legendre(i, x) for i in range(M0)]
f0_l[0](0.5)
Офлайн
alien308Вот эта вот херня во втором питоне создает переменные в объемлющем неймспейсе, то есть i из списочного выражения переползает в область видимости функции. С этим сделать ничего нельзя, просто иметь в виду[lambda x: eval_legendre(i, x) for i in range(M0)]
Отредактировано FishHook (Дек. 10, 2017 17:13:52)
Офлайн
От версии питона это не зависит. А происходит очень банальная вещь, lambda-функция получает ссылку на переменную, а не её значение. Как с этим бороться тоже вполне очевидно.
>>> s = [ lambda x: x+y for y in range(10) ] >>> [ x(i) for i, x in enumerate(s) ] [9, 10, 11, 12, 13, 14, 15, 16, 17, 18] >>> s = [ lambda x, y=y: x+y for y in range(10) ] >>> [ x(i) for i, x in enumerate(s) ] [0, 2, 4, 6, 8, 10, 12, 14, 16, 18]
Офлайн
Спасибо, заработало!
Офлайн
RodegastЕще как зависит, в третьем пофиксили
От версии питона это не зависит.
[x for x in range(10)] print(x) >>>9
[x for x in range(10)] print(x) Traceback (most recent call last): File "/Users/asmirnov/PycharmProjects/test/test.py", line 5, in <module> print(x) NameError: name 'x' is not defined
Офлайн
> Еще как зависит, в третьем пофиксили
rodegast@rodegast:~$ python3 Python 3.4.2 (default, Oct 8 2014, 10:45:20) [GCC 4.9.1] on linux Type "help", "copyright", "credits" or "license" for more information. >>> s = [ lambda x: x+y for y in range(10) ] >>> [ x(i) for i, x in enumerate(s) ] [9, 10, 11, 12, 13, 14, 15, 16, 17, 18]
Офлайн
Rodegast
some strange code
Отредактировано Slow (Дек. 11, 2017 10:12:34)
Офлайн
То же самое и у топикстартера. Проблема вообще не в области видимости, а в том, как не надо делать замыкания в питоне.
Офлайн
> Так у вас замыкание некорректно описано.
Я то я этого не знаю.
> Тут вы привели абсолютно некорректный пример.
Это иллюстрация того что “от версии питона это не зависит”.
Офлайн
https://stackoverflow.com/questions/2295290/what-do-lambda-function-closures-capture
тут суть в том, что лямбда - ленивая.
то есть, значение замыкания берется на момент вызова лямбды, а не на момент создания.
Офлайн