python自身提供了itertools, functools 和 operator来支持函数式编程

#1. itertools itertools中的函数,主要分为三类

  • 产生无限数据的迭代器, 有count(), cycle() 和 repeat()
>>> import itertools
>>> itertools.count(start[,step])  ;; start, start+step, start+2*step, ...
>>> iterator = itertools.count(5, 2)
>>> iterator.__next__()
5
>>> iterator.__next__()
7
>>> iterator.__next__()
9 

cycle(ITERABLE): cycle([‘1’, ‘2’, ‘3’, ‘4’])和cycle(“1234”)都将返回’1’, ‘2’, ‘3’, ‘4’, ‘1’, ‘2’, ‘3’, ‘4’ …的无限循环迭代器

repeat(item[,n]): 如没有传n,是无限个item的迭代器

  • 输入较短的迭代器(这里就直接将iterator转换成list输出了)
>>> import itertools
>>> list(itertools.accumulate([1, 2, 3, 4, 5])) 
[1, 3, 6, 10, 15]

>>> list(itertools.chain("ABC", "EFG"))
['A', 'B', 'C', 'E', 'F', 'G']

>>> list(itertools.compress(['A', 'B', 'C', 'D'], [0, 1, 0, 1]))
['B', 'D']

>>> list(itertools.dropwhile(lambda x: x > 5, [7,8,6,2,5,4,3]))  ;; 丢弃(drop)直到不符合(while)
[2, 5, 4, 3]

>>> list(itertools.dropwhile(lambda x: x > 5, [7,8,6,2,5,4,3]))  ;; 知道filter,也就知道filterfalse是什么意思
[2, 5, 4, 3]

>>> dictionary = {1: '2', 1: '3', 2: '2', 3: '3', 2: '5'}
>>> list(itertools.groupby(dictionary.items(), key=itemgetter(0)))
[(1, <itertools._grouper object at 0x10c9caac8>), (2, <itertools._grouper object at 0x10c9fb518>), (3, <itertools._grouper object at 0x10c9fb438>)]

>>> list(itertools.takewhile(lambda x: x > 5, [7,8,6,2,5,4,3]))  ;; dropwhile相反
[7, 8, 6]
  • 第三种是排列组合
>>> import itertools
>>> list(itertools.permutations("ABC", r=2))  ;; 排列
[('A', 'B'), ('A', 'C'), ('B', 'A'), ('B', 'C'), ('C', 'A'), ('C', 'B')]

>>> list(itertools.combinations("ABC", r=2))  ;; 组合
[('A', 'B'), ('A', 'C'), ('B', 'C')]

>>> list(itertools.product("ABC", "EFG"))
[('A', 'E'), ('A', 'F'), ('A', 'G'), ('B', 'E'), ('B', 'F'), ('B', 'G'), ('C', 'E'), ('C', 'F'), ('C', 'G')]

#2. functools

1: functools.wrap  ;;用于装饰器
一个简单的decorator
>>> def wrapper(func):
...   @functools.wraps(func)
...   def _wrapper(*args, **kwargs):
...     print("calling %s" % func.__name__)
...     return func(*args, **kwargs)
...   return _wrapper
... 
>>> @wrapper
... def add(a, b):
...   return a+b
... 
>>> add(2, 3)
calling add
5

2: partial  ;; 偏函数(固定住某函数的参数,返回另一个函数)
>>> def add(a, b):
...   return a + b
... 
>>> add_4 = functools.partial(add, b=4)  ;; 这里的add_4就是另外的函数, 固定住add函数的b参数
>>> add_4(9)
13

3: singledispatch  (请看这里: https://www.python.org/dev/peps/pep-0443/)
>>> from functools import singledispatch
>>> @singledispatch
... def get_sum(arg):
...   print(arg)
... 
>>> 
>>> @get_sum.register(list)
... def _(arg):
...   ret = sum(arg)
...   print(ret)
... 
>>> get_sum(2)
2
>>> get_sum([1,2,3,4,5,6])
21
这里的get_sum函数, 接受一个参数, 如果参数是list, 则求和, 其他类型直接输出

4: reduce
>>> reduce(lambda x, y: x+y, [1, 2, 3, 4, 5])
>>> 15  ;;((((1+2)+3)+4)+5)

5: lru_cache

#3. operator

operator主要是实现运算操作 itemgetter应该会用的到

>>> dictionary = {1: '2', 1: '3', 2: '2', 3: '3', 2: '5'}
>>> list(itertools.groupby(dictionary.items(), key=itemgetter(0)))
[(1, <itertools._grouper object at 0x10c9caac8>), (2, <itertools._grouper object at 0x10c9fb518>), (3, <itertools._grouper object at 0x10c9fb438>)]

>>> dictionary = {1: '2', 3: '3', 2: '5'}
>>> sorted(dictionary.items(), key=itemgetter(0))
[(1, '2'), (2, '5'), (3, '3')]