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