在python中,将两个函数传递到第三个二进制函数

2024-10-03 19:20:10 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在慢慢地尝试用Python进行函数式编程,但遇到了以下问题:

给定两个函数f1f2,如何构造一个函数f,用相同的参数“以函数方式”将这两个函数相乘?在

由于没有深入到函数式编程中,我有一个解决方案

f = lambda x : f1(x) * f2(x)

但它似乎不符合函数式编程的正确精神。在

我的下一个尝试是使用mul和{}运算符,如下所示

^{pr2}$

尝试将juxt的元组输出与*分割也没有成功:

^{3}$

再次使用lambda似乎是可行的,但它不知怎的挫败了整个目的。。。在

>>> temp  = juxt(f_1, f_2)
>>> f = lambda x : mul(*temp(x))

也许我在这里太迂腐了或者对Python不感兴趣,但是我觉得我在函数式编程中遗漏了一些非常重要的东西。在

有没有更实用的方法?在


Tags: lambda函数精神参数编程方式运算符解决方案
2条回答

如果你真的想对这样的高阶函数使用操作符,你可以为它做一个装饰器。在

class AddableFunction:
    '''
    Function decorator that lets (f+g)(x) = f(x) + g(x).
    '''
    def __init__(self, function):
        self._function = function
    def __call__(self, *args, **kwargs):
        return self._function(*args, **kwargs)
    def __add__(self, other):
        return AddableFunction(lambda *args, **kwargs: self(*args, **kwargs) + other(*args, **kwargs))

@AddableFunction
def f(x):
    return x ** 2

@AddableFunction
def g(x):
    return x ** 3

print((f + g)(1)) # 2
print((f + g)(2)) # 12
print((f + g)(3)) # 36

这种组合是Python和tools模块都不支持的原始操作(在某种意义上,它不能被分解为其他高阶函数)。你需要自己去实现它。在


缺少的是应用函子的概念(或者更确切地说,Python和tools模块缺少的是应用函子的概念。为了理解这意味着什么,让我们首先回顾一下tools模块中的两个函数:

  1. compose允许您将两个函数链在一起。也就是说

    compose(f,g) == lamba x: f(g(x))
    
  2. curry与部分应用有关:演示比解释快:

    ^{pr2}$

    也就是说,curry(f)(x)partial(f, x)基本相同;两者都使用一个值y来返回值f(x, y)

此外,函子基本上是一种将函数映射到某个值上的方法。你无疑熟悉列表函子:

map(f, [a,b,c]) == [f(a), f(b), f(c)]

函数也是也是函子,但是我们使用map,而不是compose。也就是说,将f映射到g上产生{}。在

现在,要将mulf1、和{}组合成{},似乎{}和{}都是有用的。也就是说

lambda x: mul(f1(x), f2(x)) == lambda x: curry(mul)(f1(x))(f2(x))

以及

lambda x: mul(f1(x), f2(x)) == lambda x: compose(curry(mul), f1)(x)(f2(x))

(也就是说,curry允许我们用另一个函数组合一个双参数函数。)

但从某种意义上讲,复合是严格意义上的线性运算,一个函数的输入来自另一个函数的输出。mulf1的组合创建一个需要参数的函数,而则返回一个需要相同参数的函数。我们如何将x移出任一表达式的“中间”?我们需要的是 神秘函数foo使得

foo(f, g) = lambda x: f(x, g(x))

这使得一个函数将其参数传递给同时传递给f和{},同时还将结果g(x)传递给f。有了这样一个函数foo,我们可以编写

lambda x: foo(compose(curry(mul), f1), f2)

得到我们想要的结果。在

这就引出了应用函子的概念。{cd25>提供必要的函数

def foo(f, g):
   def _(x):
       return f(x, g(x))

它结合了我们目前没有的构图和咖喱的概念。在

换句话说,foo是一个distinct原语操作;您不能根据组合本身来实现它。在

相关问题 更多 >