我有一个相当冗长的等式,我需要使用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函数但会给出相同输出的方法?
答案 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。
在类似的情况下,您可能也希望定义lift1
和lift3
。