包含关键字/lambda 函数的动态字典

Dynamic dictionary including keywords/ lambda function

我有一组约束,我必须在 scipy 的优化中以特定方式输入这些约束。格式如下所示

cons = ({'type' : 'eq',   'fun': lambda x:    sum(x) - 1.},
        {'type' : 'ineq', 'fun': lambda x:    bounds(x)},
        {'type' : 'ineq', 'fun': lambda x: -1*bounds(x) + 0.1})

bounds 是一个计算点积的函数。无需过多介绍,我必须在运行时手动创建字典的 cons 元组。我现在的问题是,如果它包含关键字,我如何连接/连接键和值,例如 "lambda"?

我知道如何通过字符串调用函数

def install():
    print "In install"

methods = {'install': install}
method_name = 'install' 
if method_name in methods:
     methods[method_name]() 

但是我无法理解如何让 condict 工作。 谢谢

使用您当前的结构,您可以使用此代码:

for c in cons:
    if c['type'] == type:
         fun = c['fun']
         fun(x)

其中 typex 是您的参数。

你需要写一个函数,returns一个函数。例如:

def constraint_maker(delta):
    def _(x):
        return -1*bounds(x) + delta
    return _

cons = ({'type' : 'ineq', 'fun': constraint_maker(0.1)},
        {'type' : 'ineq', 'fun': constraint_maker(0.2)},
        {'type' : 'ineq', 'fun': constraint_maker(0.3)})

名为_的函数(名字随意,可以是任何名字)是一个闭包delta 在其主体中的值由您传递给 constraint_maker.

的参数确定

注意不能写成

cons = []
for d in [0.1, 0.2, 0.3]:
    cons += {'type': 'ineq', 'fun': lambda x: -1*bounds(x) + d}

因为您的 lambda 表达式没有创建闭包;名称 d 只是一个自由变量,其值在最终调用时查找,与计算 lambda 表达式时 d 的值无关。当您在另一个函数中定义一个函数时,就会创建闭包。你可以把它写成

cons = []
for d in [0.1, 0.2, 0.3]:
    cons += {'type': 'ineq', 'fun': lambda x, d=d: -1*bounds(x) + d}

因为现在 lambda 正文中的 d 不是自由变量;它是一个局部变量(具体来说,一个参数),其默认值取自循环中同名的变量。这有点丑陋,即使不考虑两个具有相同名称(但不同范围)的变量的混淆,因为现在你的函数有 2 个参数,尽管第二个参数永远不会被显式使用。

如果我没有正确理解你的问题,你想将两个函数合二为一,例如如果你这样做:

{'type': 'eq', 'fun': lambda x: x + 1} + {'type': 'ineq', 'fun': lambda x: x + 2}

您想获得:

{'type': 'eqineq', 'fun': lambda x: x + 1 + x + 2}

如果是这种情况,请尝试以下操作:

class FunctionSum(object):
    def __init__(self, f1, f2):
        self.f1 = f1
        self.f2 = f2

    def __call__(self, x):
        return self.f1(x) + self.f2(x)

class ConstDict(dict):       
    def __add__(self, other):
        _ = {}
        for k, v in self.items():
            if hasattr(v, '__call__'):
                _[k] = FunctionSum(self[k], other[k])
            else:
                _[k] = self[k] + other[k]
        return _

const = [ConstDict({'type': 'eq', 'fun': lambda x: x + 1}),
        ConstDict({'type': 'ineq', 'fun': lambda x: x + 2})]

print (const[0] + const[1])['fun'](1)