python中的函数式编程函数compose
我不认为自己是函数式编程方面的专家,但是大量使用Haskell,Lisp和Scheme语言彻底使我的编程方式是函数式的.所以当看到web上许多对compose函数罗嗦而又复杂的实现方法后,我决定写篇文章介绍个简单却功能强大的通用实现方式.</br>
组合两个函数
把函数组合起来就是说每个函数的返回值是下一个函数的参数.例如把f和g组合起来就是f(g(x)).x是g的参数,执行的结果作为f的参数再执行,最后的结果就是组合函数的结果.</br>
我们现在定义一个函数 composer2
,它接受两个函数(f
和g
)作为参数,然后返回一个组合后的函数:</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