在python中动态构建lambda函数

时间:2013-07-12 01:18:00

标签: python scipy

假设我想生成一个函数,稍后将其合并到一组方程中,用scipy nsolve函数求解。我想创建一个这样的函数:

xi + xi + 1 + xi + 3 = 1

其中变量的数量将取决于组件的数量。例如,如果我有2个组件:

 f = lambda x: x[0] + x[1] - 1

for 3:

 f = lambda x: x[0] + x[1] + x[2] - 1

我将组件指定为要调用的函数的参数中的数组:

 def my_func(components):
        for component in components:
        .....
        .....
        return f

我不能找到这样做的方法。我必须能够这样做,因为这个函数和其他函数需要与nsolve一起解决:<​​/ p>

 x0 = scipy.optimize.fsolve(f, [0, 0, 0, 0 ....])

任何帮助将不胜感激

谢谢!


由于我不确定哪种方法最好,我会完全解释我要做的事情:

- 我正在尝试生成这两个函数,以便稍后解决:

enter image description here

enter image description here

所以我想创建一个函数teste([组件列表]),它可以返回这两个方程式(Psat(T)是一个我可以根据组件调用的函数,P是一个常量(值= 760) )。

示例:

  teste(['Benzene','Toluene'])

将返回:

xBenzene + xToluene = 1

xBenzene Psat('Benzene')+ xToluene Psat('Toluene')= 760

如果是:

   teste(['Benzene','Toluene','Cumene'])

它会返回:

xBenzene + xToluene + xCumene = 1

xBenzene Psat('Benzene')+ xToluene Psat('Toluene')+ xCumene * Psat('Cumene')= 760

所有这些x值都不是我可以计算的东西,而是变成我可以求和的列表。它们是根据我在系统中拥有的组件数量创建的变量......

希望这有助于找到最佳方法

5 个答案:

答案 0 :(得分:4)

您可以使用字符串动态构建lambda,然后使用eval函数解析它,如下所示:

a = [1, 2, 3]

s = "lambda x: "
s += " + ".join(["x[" + str(i) + "]" for i in xrange(0, 3)]) # Specify any range
s += " - 1"

print s

f = eval(s)
print f(a)

答案 1 :(得分:3)

直接翻译是:

f = lambda *x: sum(x) - 1

但不确定这是否真的是你想要的。

答案 2 :(得分:1)

我会利用numpy并做类似的事情:

def teste(molecules):
    P = np.array([Psat(molecule) for molecule in molecules])
    f1 = lambda x: np.sum(x) - 1
    f2 = lambda x: np.dot(x, P) - 760
    return f1, f2

实际上你要解决的是一个可能未确定的线性方程组,其形式为A.x = b。您可以按如下方式构建A和b:

A = np.vstack((np.ones((len(molecules),)),
               [Psat(molecule) for molecule in molecules]))
b = np.array([1, 760])

然后你可以创建一个lambda函数,返回一个2元素向量:

return lambda x: np.dot(A, x) - b

但我真的不认为这是解决方程式的最佳方法:要么你有np.linalg.solve(A, b)可以获得的单一解决方案,要么你有一个无限多解决方案的线性系统,在这种情况下您想要找到的是解空间的基础,而不是该空间中的单个点,这是您将从函数作为输入的数值解算器中获得的。

答案 3 :(得分:0)

如果你真的想通过迭代建立来定义一个函数,你可以。我想不出任何情况会是最好的答案,甚至是合理的答案,但这就是你要求的,所以:

def my_func(components):
    f = lambda x: -1
    for component in components:
        def wrap(f):
            return lambda x: component * x[0] + f(x[1:])
        f = wrap(f)
    return f

现在:

>>> f = my_func([1, 2, 3])
>>> f([4,5,6])
44

当然,这对调试来说并不好玩。例如,查看调用f([4,5])的追溯。

答案 4 :(得分:-1)

def make_constraint_function(components):
    def constraint(vector):
        return sum(vector[component] for component in components) - 1
    return constraint

你可以用lambda做,但命名函数可能更具可读性。 def馈送函数可以执行lambdas可以执行的任何操作。确保为函数提供了一个好的文档字符串,并使用适合您程序的变量和函数名称。