函数式编程除去本身一套的哲学之外,在python中通常可以起到简化代码,增强程序的可读性的作用,一般提起python函数式编程都会涉及到itertools
,functools
,operator
等模块的讲解,以及内置的map
、reduce
、filter
、all
、any
、enumerate
、zip
等函数的用法,本篇文章需要同学在对上述三方库和内置函数有一定理解的基础上来进一步了解使用toolz
模块。
toolz
模块的源码在这里
下面通过一些简单的例子来说明利用toolz进行函数式编程的方法(程序运行环境为python3.6)
首先定义一些简单的函数和样例数据备用
data = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
def square(x):
return x ** 2
def iseven(n):
return n % 2 == 0
def add(x, y):
return x + y
def mul(x, y):
return x * y
def lesser(x, y):
if x < y:
return x
else:
return y
def greater(x, y):
if x > y:
return x
else:
return y
内置的map
函数, 即将第一个参数传入的函数作用与第二参数传入的列表,注意在python3中map
、filter
等返回的是一个迭代器,所以想要得到全部的值需要用list转换一下。
list(map(square, data))
#>>> [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
map
的作用方式类似于numpy
数组的广播方式(broadcasting)
import numpy as np
X = np.arange(1, 11)
X**2
#>>> array([ 1, 4, 9, 16, 25, 36, 49, 64, 81, 100])
还可以用列表解析的方式等价于map
的作用方式
res = [square(d) for d in data]
#>>> [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
下面是filter
函数,第一个参数为函数,第二个为数据列表,返回列表中使函数值为真的数据。
list(filter(iseven, data))
#>>> [2, 4, 6, 8, 10]
reduce
的用法如下,即将列表中的元素从左到右累计计算,计算的结果作为参数继续向后传递,最终得到一个结果。注意,reduce
的第三个参数可以传入一个初始值,从而影响最后的结果。
from functools import reduce
#reduce函数在py3中放在了functools里
reduce(add,data)
#>>> 55
reduce(add,data,10)
#>>> 65
lambda
函数即匿名函数,结合上面的map
、reduce
等方法通常能够使得代码简洁,十分方便。下面以lambda
来实现内置的求和函数。
sum_ = lambda data: reduce(add,data,0)
sum_(data)
#>>> 55
下面终于到toolz
出场了。toolz.groupby
可以看做是上面filter
的增强版,不仅可以输出满足条件的子列表,还可以将数据划分到相关的不同集合
groupby(iseven, data)
#>>> {False: [1, 3, 5, 7, 9], True: [2, 4, 6, 8, 10]}
groupby(lambda n: n % 3, data)
#>>> {0: [3, 6, 9], 1: [1, 4, 7, 10], 2: [2, 5, 8]}
groupby(len, ['Alice', 'Bob', 'Charlie', 'Dan', 'Edith', 'Frank'])
# >>> {3: ['Bob', 'Dan'], 5: ['Alice', 'Edith', 'Frank'], 7: ['Charlie']}
接下来将会介绍更多toolz的相关用法。。。