繁体   English   中英

在Python中创建动态大小的lambdas列表,但它们彼此完全相同

[英]Creating list of lambdas in Python of dynamic size, but they all are identical to each other

所以我试图动态地生成反正切(反正切)的泰勒级数展开,作为要包括的项数的函数。 函数arctan(x)= x - (x ^ 3)/ 3 +(x ^ 5)/ 5 - ...

我的代码如下:

terms = [lambda a: pow(-1.0, i) * pow(a, 1.0 + 2.0 * i) /(1.0 + 2.0 * i) \
    for i in range(term_num)]

我也尝试使用for循环制作术语:

terms = []
for i in range(term_num): terms.append(lambda a: \
    pow(-1.0, i) * pow(a, 1.0 + 2.0 * i) /(1.0 + 2.0 * i))

但是,当我跑

for term in terms: print(term, term(x))

我得到以下输出(对于x = 0.2,term_num = 5:

<function arctan.<locals>.<lambda> at 0x10e48f730> 5.68888888889e-08
<function arctan.<locals>.<lambda> at 0x5609e5bf8> 5.68888888889e-08
<function arctan.<locals>.<lambda> at 0x55f4c5048> 5.68888888889e-08
<function arctan.<locals>.<lambda> at 0x5609eee18> 5.68888888889e-08
<function arctan.<locals>.<lambda> at 0x5609fb598> 5.68888888889e-08

并且对于x = 1/239,term_num = 6

<function arctan.<locals>.<lambda> at 0x560a7cc80> -6.255044509921559e-28
<function arctan.<locals>.<lambda> at 0x5608642f0> -6.255044509921559e-28
<function arctan.<locals>.<lambda> at 0x560a3af28> -6.255044509921559e-28
<function arctan.<locals>.<lambda> at 0x10b07fa60> -6.255044509921559e-28
<function arctan.<locals>.<lambda> at 0x560818400> -6.255044509921559e-28
<function arctan.<locals>.<lambda> at 0x55fa97378> -6.255044509921559e-28

这些始终是扩展中应该给出的最后一个值,但出于某种原因,对于所有术语。

对于term_num和x的其他值也会发生这种情况。 我甚至尝试过深度复制,因为我担心我以某种方式在lambda中用作参考,但它不会改变输出。 将i作为float转换也不会改变计算。

我究竟做错了什么? 我似乎成功地产生了不同的lambdas(通过引用),但由于某种原因,它们的内容都是相同的,由最后一个术语决定。

这是由于Python如何绑定闭包中的变量。 共同的陷阱

Python的闭包是后期绑定。 这意味着在调用内部函数时会查找闭包中使用的变量值。

这里,每当调用任何返回的函数时,在调用时在周围的范围中查找i的值。 到那时,循环已经完成,我的最终值为4。

(其中i引用该页面上的一个示例,但对您的案例同样有效。)

我喜欢他们建议的使用functools.partial解决方法:

from functools import partial
from operator import mul

def create_multipliers():
    return [partial(mul, i) for i in range(5)]

在您的情况下,您可以编写一个辅助函数,然后部分应用它:

def term(i, a):
    return pow(-1.0, i) * pow(a, 1.0 + 2.0 * i) / (1.0 + 2.0 * i)

terms = [partial(term, i) for i in range(term_num)]

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM