[英]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.