动态字典包括关键字/ lambda函数

时间:2016-03-16 20:33:43

标签: python dictionary dynamic lambda constraints

我有一组约束,我必须在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是计算点积的函数。在不进行太多细节的情况下,我必须在运行时手动创建字典的元组。我现在的问题是,如果它包含关键字,例如“lambda”,我如何连接/加入键和值?

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

def install():
    print "In install"

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

但是我无法理解我如何能够使用这种方法。 感谢

3 个答案:

答案 0 :(得分:2)

您需要编写一个返回函数的函数。例如:

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只是一个自由变量,其值在最终被调用时被查找,并且在评估d表达式时与lambda的值无关。在另一个函数中定义函数时会创建闭包。您可以将其写为

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

因为d正文中的lambda现在不是自由变量;它是一个局部变量(特别是一个参数),其默认值取自循环中同名变量。这有点丑陋,甚至除了两个具有相同名称(但是不同的范围)的变量的混淆之外,因为现在你的函数需要2个参数,尽管第二个参数永远不会被明确使用。

答案 1 :(得分:0)

如果我正确理解了您的问题,您希望将两个功能组合成一个,例如:如果你这样做:

{'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)

答案 2 :(得分:-1)

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

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

其中typex是您的参数。