在python中使用相同的运算符添加lambda函数

时间:2015-12-14 07:03:17

标签: python numpy scipy

我有一个相当冗长的等式,我需要使用scipy.integrate.quad进行整合,并且想知道是否有办法将lambda函数相互添加。我的想法是这样的

y = lambda u: u**(-2) + 8
x = lambda u: numpy.exp(-u)
f = y + x
int = scipy.integrate.quad(f, 0, numpy.inf)

我真正使用的方程式远比我在这里暗示的要复杂得多,因此为了便于阅读,将方程式分解为更小,更易于管理的部分会很有用。

有没有办法处理lambda函数?或者也许是另一种甚至不需要lambda函数但会给出相同输出的方法?

5 个答案:

答案 0 :(得分:17)

在Python中,您通常只使用lambda来实现非常简短的函数,这些函数很容易适应创建它们的行。 (有些语言有其他意见。)

正如@DSM在评论中暗示的那样,lambdas本质上是创建函数的捷径,因为它不值得为它们命名。

如果您正在做更复杂的事情,或者如果您需要为代码命名以供日后参考,那么lambda表达式对您来说不是一个快捷方式 - 相反,您可能会好def是一个普通的老函数。

因此,不要将lambda表达式赋值给变量:

y = lambda u: u**(-2) + 8

您可以将该变量定义为函数:

def y(u):
    return u**(-2) + 8

这给了你一些解释,或者更复杂,或者你需要做什么的空间:

def y(u):
    """
    Bloopinate the input

    u should be a positive integer for fastest results.
    """
    offset = 8
    bloop = u ** (-2)
    return bloop + offset

函数和lambda都是"可调用的",这意味着就scipy.integrate.quad()而言,它们基本上是可互换的。

要组合callables,您可以使用几种不同的技术。

def triple(x):
   return x * 3

def square(x):
   return x * x

def triple_square(x):
   return triple(square(x))

def triple_plus_square(x):
    return triple(x) + square(x)

def triple_plus_square_with_explaining_variables(x):
    tripled = triple(x)
    squared = square(x)
    return tripled + squared

如果它让你的代码更清晰(它可能赢了),我会考虑更高级的选项。例如,您可以将callable放在列表中:

 all_the_things_i_want_to_do = [triple, square]

一旦他们进入列表,您就可以使用基于列表的操作来处理它们(包括将它们依次应用到reduce列表中的单个值。

但是如果你的代码和大多数代码一样,那些只是按名称相互调用的常规函数​​将是最简单的编写和最容易阅读的。

答案 1 :(得分:11)

没有内置功能,但你可以很容易地实现它(当然会有一些性能损失):

import numpy

class Lambda:

    def __init__(self, func):
        self._func = func

    def __add__(self, other):
        return Lambda(
            lambda *args, **kwds: self._func(*args, **kwds) + other._func(*args, **kwds))

    def __call__(self, *args, **kwds):
        return self._func(*args, **kwds)

y = Lambda(lambda u: u**(-2) + 8)
x = Lambda(lambda u: numpy.exp(-u))

print((x + y)(1))

可以以类似的方式添加其他运营商。

答案 2 :(得分:10)

使用sympy,您可以执行以下功能操作:

>>> import numpy
>>> from sympy.utilities.lambdify import lambdify, implemented_function
>>> from sympy.abc import u
>>> y = implemented_function('y', lambda u: u**(-2) + 8)
>>> x = implemented_function('x', lambda u: numpy.exp(-u))
>>> f = lambdify(u, y(u) + x(u))
>>> f(numpy.array([1,2,3]))
array([ 9.36787944,  8.13533528,  8.04978707])

答案 3 :(得分:4)

使用下面的代码,以尽可能多写 less code 来获得相同的结果:

y = lambda u: u**(-2) + 8
x = lambda u: numpy.exp(-u)
f = lambda u, x=x, y=y: x(u) + y(u)
int = scipy.integrate.quad(f, 0, numpy.inf)

答案 4 :(得分:3)

作为一名功能性程序员,我建议将解决方案概括为applicative combinator

In [1]: def lift2(h, f, g): return lambda x: h(f(x), g(x))
In [2]: from operator import add
In [3]: from math import exp
In [4]: y = lambda u: u**(-2) + 8
In [5]: x = lambda u: exp(-u)
In [6]: f = lift2(add, y, x)
In [7]: [f(u) for u in range(1,5)]
Out[7]: [9.367879441171443, 8.385335283236612, 8.160898179478975, 8.080815638888733]

使用lift2,您可以使用任意二进制函数以无点的方式组合两个函数的输出。 operator中的大部分内容应该足以用于典型的数学组合,避免编写任何lambdas。

在类似的情况下,您可能也希望定义lift1lift3

相关问题