2014-04-09 74 views
2

我喜歡用參數列表定義一個函數列表,以便從有限數量的單極子和偶極子實際組成一個電位。函數列表的奇怪行爲

但是,由於某種原因,python列表中的函數並沒有像我期望的那樣運行。

以下示例:

def function(coefficients): 
    phi = [] 
    i = 0 
    for y in coefficients: 
    f = lambda x: y*(x**i) 
    i += 1 
    phi.append(f) 
    print f(2) 
    return phi 

> phi = function([1,2,3]) 
2 
8 
24 

> k0 = phi[0] 
> k1 = phi[1] 
> k2 = phi[2] 

> print k0(2), k1(2), k2(2) 
24 24 24 

始終在列表中的最後一個函數檢索獨立於功能從列表中挑選的。

任何想法?

在此先感謝。

+2

f將使用y的最後已知值,而不是創建lambda時y的值。另請參見[Python嵌套函數中的局部變量](http://stackoverflow.com/questions/12423614/local-variables-in-python-nested-functions) – Kevin

回答

5

由於閉包屬性,lambda函數持有對變量y的引用。所以,所有的函數都有對同一個對象的引用,它們將在調用過程中得到最後一個值y。爲了解決這個問題,

f = lambda x,y=y,i=i: y*(x**i) 

現在,我們已經創造了另一個參數y並具有默認值y。它使功能取決於現在的本地參考。所以,即使y的值在循環中發生變化,lambda函數也不再指y

注:同樣的解釋也適用於變量i

爲了使事情很清楚,我會建議使用不同的變量名

f = lambda x, z=y, j=i: z * (x ** j) 

注:您的原始輸出是2 8 24。這是因爲,當你調用函數時,i得到增加,我不認爲這是你真正想要的。實際輸出應該是1 4 12

+0

謝謝。使用默認值的好解決方案。最初嘗試使用deepcopy來解析lambda函數中參數的重新定義,但沒有意識到deepcopy也是在lambda函數執行時執行的,因此該參數已被重新定義。因此,相當混亂的是怎麼回事。再次感謝。 – YetAnotherCoda

+0

@ user3515972很高興能有幫助:)如果您覺得我的回答對您有幫助,您可以[接受我的回答](http://meta.stackexchange.com/a/5235/192545)。 – thefourtheye