python中的函数式编程函数compose

2017-03-04  本文已影响0人  gmsy

python中的函数式编程函数compose

我不认为自己是函数式编程方面的专家,但是大量使用Haskell,Lisp和Scheme语言彻底使我的编程方式是函数式的.所以当看到web上许多对compose函数罗嗦而又复杂的实现方法后,我决定写篇文章介绍个简单却功能强大的通用实现方式.</br>

组合两个函数

把函数组合起来就是说每个函数的返回值是下一个函数的参数.例如把f和g组合起来就是f(g(x)).x是g的参数,执行的结果作为f的参数再执行,最后的结果就是组合函数的结果.</br>
我们现在定义一个函数 composer2 ,它接受两个函数(fg)作为参数,然后返回一个组合后的函数:</br>

def composer2(f,g):
  return lambda x:f(g(x))

例如:

>>> def double(x):
...     return x * 2
...
>>> def inc(x):
...     return x + 1
...
>>> inc_and_double = compose2(double, inc)
>>> inc_and_double(10)
22

组合n个函数

现在我们知道怎么组合两个函数了,那推广到组合n个函数一定蛮有趣.既然我们有了composer2这个函数,让我们试着在composer2基础上组合3个函数.

>>> def dec(x):
...     return x - 1
...
>>> inc_double_and_dec = compose2(compose2(dec, double), inc)
>>> inc_double_and_dec(10)
21

看到这里的模式没?首先我们组合两个函数,成为一个新函数,然后我们组合这个新函数和下一个函数,以此类推......</br>
让我们用python写出来.</br>

import functools

def compose(*functions):
    def compose2(f, g):
        return lambda x: f(g(x))
    return functools.reduce(compose2, functions, lambda x: x)

或者你喜欢更紧凑的方式:
</br>

def compose(*functions):
    return functools.reduce(lambda f, g: lambda x: f(g(x)), functions, lambda x: x)

例子:</br>

>>> inc_double_and_dec = compose(dec, double, inc)
>>> inc_double_and_dec(10)
21

多参数的函数

支持多参数有点费事,不过完全不必要这么做.因为任何函数都能转化为只接受一个参数.高阶函数中的奇技淫巧比如柯里化,装饰器,或者我们自己写.</br>
例如:

>>> def second(*args):
...     return args[1]
...
>>> def second_wrapper(lst):
...     return second(*lst)
...
>>> pipeline = compose(second_wrapper, list, range)
>>> pipeline(5)
1
>>> def sub(a, b):
...     return a - b
...
>>> pipeline = compose(functools.partial(sub, b=4), operator.neg)
>>> pipeline(-6)
2

如果你想学习python中的函数式编程,我建议这个文档
翻译自:Mathieu Larose

上一篇 下一篇

猜你喜欢

热点阅读