Python - 函数是任意许多其他函数的总和

时间:2017-02-21 15:20:35

标签: python function sum combinations linear

HeJ小鼠!我试图在Python中为多项式 p 编写一个函数,它是 n 基函数 phi_i 的线性组合。如何定义一个本身是 n 其他函数之和的函数?

我知道这有效:

phi1 = lambda x: x**2
phi2 = lambda x: x
p = lambda x: phi1(x) + phi2(x)

但如果我尝试这样的循环:

p = lambda x: 0
for i in range(0,n):
    p = lambda x: p(x)+phi[i](x)

其中phi是我的基函数列表,我创建了一个无限循环。

我查了Writing a function that is sum of functions,但不幸的是,这不是Python。

2 个答案:

答案 0 :(得分:3)

您可以通过将简单的生成器表达式传递给sum

来完成此操作
def sigma(funcs, x):
    return sum(f(x) for f in funcs)

phi = [lambda x: x**2, lambda x: x]
y = sigma(phi, x)

顺便说一句,将lambda用于命名函数被认为是不好的风格,它应该用于匿名函数。

如果您希望每次调用时都不需要传递phi的函数,那么有几种方法可以实现。最简单的方法是在函数中使用phi。例如,

def sigma(x):
    return sum(f(x) for f in phi)

但是,这有一些缺点。如果phi不在您致电sigma的范围内,那么它将无法运作;你可以通过使phi全局化来解决这个问题,但这可能不方便,并且在没有必要的情况下避免使用全局变量是最好的。另一个缺点是它使用phi的当前内容,而不是定义sigma时的内容,因此如果您修改phi的内容,这些更改将反映在sigma中{1}},这可能是也可能不是。

另一种选择是使用closure来创建函数。然后我们不会受范围问题的影响:您可以在原始函数列表不可见的范围内调用生成的求和函数。我们还可以创建功能列表的副本,因此不会受到传入函数列表更改的影响。

def make_adder(funcs):
    # Copy the function list 
    funcs = funcs[:]
    def sigma(x):
        return sum(f(x) for f in funcs)
    return sigma

phi = [lambda x: x**2, lambda x: x]
sigma = make_adder(phi)
y = sigma(x)

另一种选择是使用原始sigma并将phi函数传递给functools.partial,例如

from functools import partial
sig = partial(sigma, phi)
y = sig(x)

答案 1 :(得分:1)

直接回答OP

将您的phis存储在list

phis = [
    lambda x: x**2,
    lambda x: x,
]
p = lambda x: sum(phi(x) for phi in phis)

进一步考虑

如果你想要实现多项式,我会建议类似的东西:

def poly(c):
    return lambda x: sum(f(x) for f in [lambda x, i=i: c[i]*x**i for i in range(len(c))])

poly函数接受一个序列作为唯一参数,其元素必须是intfloat。第一个元素被指定为x ^ 0的系数,第二个元素被指定为x ^ 1,依此类推。所以你的例子(p(x)= x + x ^ 2)最终会像这样构造:p = poly([0, 1, 1])

另一种选择是接受任意数量的参数,其中每个参数都需要是intfloat,而不是第一个是序列。这只需要在函数声明中添加一个*

def poly(*c):
    return lambda x: sum(f(x) for f in [lambda x, i=i: c[i]*x**i for i in range(len(c))])

要使用此功能构建示例,您不需要列表:p = poly(0, 1, 1)

这些方法中的任何一个都会创建一个可以按照您的预期调用的多项式函数:p(1)将返回2p(2)将返回6,依此类推。

功能说明

def poly(c):
    # Create a list where we are gonna store the functions for every term in the polynomial
    terms = []
    # Create as many terms as the arguments length
    for i in range(len(c)):
        # Each term is the product of the nth coefficient from c and x to the power of n
        terms.append(lambda x, n=i: c[n]*x**n)
        # The second parameter n is needed because if we pass i directly
        # inside the function algorithm, Python wouldn't check its value
        # inmediately, but when it gets executed, and by then the loop will
        # be finished and i would be constant for every term. This argument
        # is not exposed to the polynomial function as the next lambda only
        # has one argument, so there is no way to wrongly call this function
    # We return a function that adds the result of every term
    return lambda x: sum(f(x) for f in terms)