2015-07-10 137 views
1

我使用scipy優化最小化包。爲了爲我的問題提供約束,我需要創建一個龐大的元組。我這樣做以下列方式:python中lambda函數的列表參數

c0 = []; 
count = 0; 
for i in range(0, Nx): 
    for j in range(0, Ny): 
     c0.append({'type': 'eq', 'fun': lambda x: x[count]*x[count] + x[T + count]*x[T + count] + x[2*T + count]*x[2*T + count] - 1.}); 
     count+=1; 
cons = tuple(c0); 

但當極小需要他們來使用,總是需要的count終值,這顯然會導致成index out of bounds錯誤。嘗試del(count)導致了另一個錯誤,所以我想我的lambda函數用法的python方式的理解有問題。也許有更好的,使用切片和東西的python風格的方式?將不勝感激任何幫助。

+2

lambda中的名稱將計算爲lambda運行時名稱的值,而不是創建時的值。這解釋了您的終端計數問題。有關更多信息,請參見[Python嵌套函數中的局部變量](http://stackoverflow.com/q/12423614/953482)。 – Kevin

回答

4

變量中的count變量在您調用lambda函數時進行評估,而不是在創建它時(與其他語言不同)。你需要做的是迫使該變量的副本,一個辦法可以使用閉包:

c0.append({ 
     'type': 'eq', 
     'fun': (lambda count: lambda x: x[count]*x[count] + x[T + count]*x[T + count] + x[2*T + count]*x[2*T + count] - 1.) (count) 
}); 

另一種方式(IMO取巧的辦法)被作爲一個參數的默認值使用方法:

c0.append({ 
    'type': 'eq', 
    'fun': lambda x, count = count: x[count]*x[count] + x[T + count]*x[T + count] + x[2*T + count]*x[2*T + count] - 1. 
}); 
+0

非常感謝您的快速響應!那正是我想要的! –

0

你在那裏做的是創建一個函數對象,其中引用一個變量,它不創建自己的副本,所以當你去執行該函數時,它查找變量,它現在有循環中的最後一個值。

@Holt closure可能是完成任務的最安全的方法,儘管有點複雜。我會在閉包中更改變量的名稱,以便更清楚地瞭解正在發生的事情。

這樣做是創建一個單獨的作用域,以便一旦執行離開外部lambda函數(調用它並返回一個值,它是您實際需要的函數對象)時,函數對象中的count變量和count變量在循環中不再引用內存中的相同位置,並且可以遞增計數器而不影響該函數引用的變量。