生成lambda函数组合

时间:2018-03-01 10:31:05

标签: python design-patterns lambda functional-programming

我面临一个具有挑战性的问题,以使我的Python3代码更优雅。

假设我有一个具有可变数量的不同输入的数字函数,例如:

def fun1(a,b):
    return a+b

def fun2(c,d,e):
    return c*d + e

def fun3(x):
    return x*x

这些函数需要在单个函数中聚集,需要将其用作数值解算器的优化函数。

然而,我需要使用这些函数创建不同操作的不同组合,例如将前两个函数的输出相乘并乘以第三个函数求和。

手动解决方案是创建一个特定的lambda函数:

fun = lambda x : fun1(x[0],x[1])*fun2(x[2],x[3],x[4]) + fun3(x[4])

但我拥有的函数数量很大,我需要生成它们的所有可能组合。 我希望能够系统地组合这些函数,并始终知道从更高级函数fun的参数到每个单个函数的低级参数的映射。 在这种情况下,我手动指定x[0]对应a的参数fun1x[1]对应b等的参数fun1。< / p>

有什么想法吗?

2 个答案:

答案 0 :(得分:2)

听起来你正在尝试做所谓的symbolic regression。这个问题通常通过遗传算法的一些变化来解决,遗传算法编码基因中的功能关系,然后根据适应度函数进行优化,其中包括预测误差以及惩罚更复杂关系的术语。

以下是两个为您解决此问题的库:

以下类提供了组成函数和跟踪每个函数所需参数数量的基本方法,这似乎是您遇到的主要问题:

class Wrapper:
    def __init__(self, f):
        self.f = f
        self.n = f.__code__.co_argcount

    def __call__(self, x):
        return self.f(*x)

    def __add__(self, other):
        return Add(self, other)

    def __mul__(self, other):
        return Mul(self, other)

class Operator:
    def __init__(self, left, right):
        self.left = left
        self.right = right
        self.n = left.n + right.n

class Mul(Operator):
    def __call__(self, x):
        return self.left(x[:self.left.n]) * self.right(x[self.left.n:])

class Add(Operator):
    def __call__(self, x):
        return self.left(x[:self.left.n]) + self.right(x[self.left.n:])

要使用它们,首先要为每个函数创建包装器:

w1 = Wrapper(fun1)
w2 = Wrapper(fun2)
w3 = Wrapper(fun3)

然后,您可以添加和乘以包装器以获得类似函数的新对象:

(w1 + w2*w3)([1, 2, 3, 4, 5, 6])

答案 1 :(得分:0)

这可能是一个解决方案:

def fun1(a,b):
    return a+b

def fun2(c,d,e):
    return c+d+e


def compose(f1,f2):
    n1 = len(f1.__code__.co_varnames)
    n2 = len(f2.__code__.co_varnames)

    F1 = lambda x : f1(*[x[i] for i in range(0,n1)])*f2(*[x[i] for i in range(n1,n1+n2)])
    return F1

print(compose(fun1,fun2)([1,2,3,4,5]))