在python

时间:2015-07-10 12:27:55

标签: python lambda scipy

我使用scipy优化最小化包。为了给我的问题提供约束,我需要创建一个巨大的元组。我是通过以下方式完成的:

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 个答案:

答案 0 :(得分:4)

调用lambda函数时,会计算变量中的count变量,而不是在创建它时(与其他语言不同)。您需要做的是强制使用此变量的副本,一种方法是使用闭包:

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.
});

答案 1 :(得分:0)

你在那里做的是创建一个引用变量的函数对象,它不创建自己的副本,这样当你去执行该函数时,它会查找变量,现在具有循环中的最后一个值。

@Holt关闭可能是完成任务的最安全的方法,虽然有点复杂。我会在闭包中更改变量的名称,以使其更清晰。

这样做是创建一个单独的作用域,这样一旦执行离开外部lambda函数(调用它并返回一个值,它是你真正想要的函数对象)你的函数对象中的count变量和count中的count变量你的循环不再引用内存中的相同位置,你可以递增计数器而不影响函数引用的变量。