我面临一个具有挑战性的问题,以使我的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
的参数fun1
,x[1]
对应b
等的参数fun1
。< / p>
有什么想法吗?
答案 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]))