在 python 中列出 lambda 函数的参数

List argument for a lambda function in python

我使用 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 风格的方式来使用切片之类的东西?非常感谢任何帮助。

变量中的 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.
});

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

@Holt 闭包可能是完成任务的最安全方法,尽管有点复杂。我会在闭包中更改我的变量的名称,以使发生的事情更清楚。

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