函数式编程模块
- itertools模块
- functools模块
- operator模块
itertools
-
itertools.count(start=0, step=1)
创建一个迭代器,它从 start 值开始,返回均匀间隔的值。类似如下代码:
def count(start=0, step=1): """ count(5,5) -> 5 10 15 20 25 30 ... """ n = start while True: yield n n += step
-
itertools.cycle(iterable)
无限循环的迭代iterable中的元素。类似如下代码:
def cycle(iterable): """ cycle("ABC") -> A B C A B C A B C ... """ data = list(iterable) while True: for d in data: yield d
-
itertools.repeat(object, times=None)
创建一个迭代器,不断重复 object 。除非设定参数 times ,否则将无限重复。
def repeat(obj, times=None): if times is None: while True: yield obj else: for i in range(times): yield obj
-
itertools.chain(*iterables)
创建一个迭代器,它首先返回第一个可迭代对象中所有元素,接着返回下一个可迭代对象中所有元素,直到耗尽所有可迭代对象中的元素。类似如下代码:
def chain(*iterables): """ chain("ABC",[1,2,3]) -> A B C 1 2 3 """ for iterable in iterables: for elem in iterable: yield elem
-
itertools.combinations(iterable, r)
返回由输入 iterable 中元素组成长度为 r 的子序列(iterable中元素长度为r的组合)。
>>> import itertools >>> >>> for combination in itertools.combinations("ABCD",3): ... print(combination) ... ('A', 'B', 'C') ('A', 'B', 'D') ('A', 'C', 'D') ('B', 'C', 'D')
-
itertools.permutations(iterable, r=None)
连续返回由 iterable 元素生成长度为 r 的排列。
如果r为None,默认为len(iterable)。
>>> for x in itertools.permutations("123"): ... print(x) ... ('1', '2', '3') ('1', '3', '2') ('2', '1', '3') ('2', '3', '1') ('3', '1', '2') ('3', '2', '1')
-
itertools.compress(data, selectors)
创建一个迭代器,它返回 data 中经 selectors 真值测试为
True
的元素(迭代器在两者较短的长度处停止)。大致相当于:def compress(data, selectors): """ compress("ABCDEF",[0,0,1,1,0,1]) -> C D F """ return (d for d, s in zip(data,selectors) if s)
-
itertools.filterfalse(predicate, iterable)
创建一个迭代器,只返回 iterable 中 predicate 为
False
的元素。如果 predicate 是None
,返回真值测试为False
的元素(内置函数filter的相反操作)。相当于以下代码:def filterfalse(predicate, iterable): """ filterfalse(lambda x:x%2, range(10)) -> 2 4 6 8 """ if predicate is None: predicate = bool for elem in iterable: if not predicate(elem): yield elem
-
itertools.islice(iterable, stop)
itertools.islice(iterable, start, stop[, step])
创建一个迭代器,返回从 iterable 里选中的元素。
>>> L = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] >>> list(itertools.islice(L,5)) [0, 1, 2, 3, 4] >>> list(itertools.islice(L,2,5)) [2, 3, 4] >>> list(itertools.islice(L,2,7,2)) [2, 4, 6]
-
itertools.zip_longest(*iterables, fillvalue=None)
-
内置函数zip(*iterables)
创建一个迭代器,从每个可迭代对象中收集元素,迭代持续到耗光最短的可迭代对象。
>>> for d in zip("ABCD","123"): ... print(d) ... ('A', '1') ('B', '2') ('C', '3')
-
zip_longest(*iterables, fillvalue=None)
创建一个迭代器,从每个可迭代对象中收集元素。如果可迭代对象的长度未对齐,将根据 fillvalue 填充缺失值。迭代持续到耗光最长的可迭代对象。
>>> for d in itertools.zip_longest("ABCD","123"): ... print(d) ... ('A', '1') ('B', '2') ('C', '3') ('D', None) >>> >>> for d in itertools.zip_longest("ABCD","123",fillvalue="*"): ... print(d) ... ('A', '1') ('B', '2') ('C', '3') ('D', '*') >>>
-
-
itertools.takewhile(predicate, iterable)
创建一个迭代器,只要 predicate 为真就从可迭代对象中返回元素。大致相当于:
def takewhile(predicate, iterable): for x in iterable: if predicate(x): yield x else: break
functools
-
@functools.lru_cache(maxsize=128, typed=False)
functools.lru_cache实现了备忘功能,它把耗时的函数结果缓存在字典里,所以函数的位置参数或关键字参数必须是可hash的。
- 如果将maxsize设置为
None
,则禁用LRU功能,缓存可以无限制地增长;当maxsize是2的幂时,LRU功能表现最佳。 - 如果typed设置为true,则将分别缓存不同类型的函数参数。例如,
f(3)
、f(3.0)
将被视为产生截然不同的结果而被缓存。
如下,使用高速缓存实现计算有效Fibonacci数的示例:
>>> from functools import lru_cache >>> @lru_cache() ... def fibonacci(n): ... if n<2: ... return 1 ... else: ... return fibonacci(n-1)+fibonacci(n-2) ... >>> fibonacci(10) 89 >>> fibonacci(100)#如果不用lru缓存,则此列需要计算tooooloooooongtime 573147844013817084101 >>> [fibonacci(i) for i in range(10)] [1, 1, 2, 3, 5, 8, 13, 21, 34, 55] >>>
- 如果将maxsize设置为
-
functools.partial(func, *args, **keywords)
偏函数(Partial function)是通过将一个函数的部分参数预先绑定为某些值,从而得到一个新的具有较少可变参数的函数。
例子:Django发送邮件——绑定from_email参数,简化代码
import functools ... def _send_email(subject, message, from_email, recipient): send_email(subject, message, from_email, recipient) email_admin = functools.partial(_send_email, from_email="admin@example.com") market_admin = functools.partial(_send_email, from_email="market@example.com") market_system_account = functools.partial(_send_email, from_email=settings.EMAIL_HOST_USER) ...
-
functools.reduce(function, iterable[, initializer])
reduce
第一个参数function
为一个函数,第二个参数iterable
为一个序列。rudece
函数作用是把iterable
中的第1个和第2个元素代入function
,得到一个值,并把这个值和iterable
第3个元素作为参数传入function
,以此类推…最终得到一个值。>>> import functools >>> import operator >>> functools.reduce(operator.add,range(100)) 4950 >>> sum(range(100)) 4950
-
@functools.singledispatch
将函数转换为单调度泛型函数。
import functools @functools.singledispatch def single(arg): print(arg) @single.register(float) @single.register(int) def _(arg): if type(arg) is float: print("Float:",arg) else: print("Int:",arg) @single.register(complex) def _(arg): print("Complex(%r,%r)"%(arg.real,arg.imag)) @single.register(str) def _(arg): print("Str:",arg) @single.register(list) def _(arg): print("List:",arg)
>>> single(3) Int: 3 >>> single(2.6) Float: 2.6 >>> single("Hello world") Str: Hello world >>> single([1,2,3,4,5]) List: [1, 2, 3, 4, 5] >>> single(complex(1,2)) Complex(1.0,2.0)
-
@functools.wraps(wrapped, assigned=WRAPPER_ASSIGNMENTS, updated=WRAPPER_UPDATES)
定义函数装饰器。
例子:不使用functools.wraps装饰器
def tracer(func): def wrapper(*args, **kwargs): """wrapper n!""" result = func(*args,**kwargs) print("%s(%r,%r)->%r"%(func.__name__,args,kwargs,result)) return result return wrapper @tracer def factorial(n): """return n!""" return 1 if n < 2 else n*factorial(n-1)
>>> factorial.__name__ 'wrapper' >>> factorial.__doc__ 'wrapper n!'
@装饰器语句等价于
factorial=tracer(factorial)
,即factorial=wrapper
;由演示结果看出,最后的factorial函数对象变成了wrapper,而非factorial函数。例子:使用functools.wraps装饰器
import functools def tracer(func): @functools.wraps(func) def wrapper(*args, **kwargs): """wrapper n!""" result = func(*args,**kwargs) print("%s(%r,%r)->%r"%(func.__name__,args,kwargs,result)) return result return wrapper @tracer def factorial(n): """return n!""" return 1 if n < 2 else n*factorial(n-1)
>>> factorial.__name__ 'factorial' >>> factorial.__doc__ 'return n!'
operator
operator
模块提供了一套与Python的内置运算符对应的高效率函数。
函数 | 描述 |
---|---|
operator.abs(x) | abs(x) |
operator.add(a,b) | a+b |
opeartor.mod(a,b) | a%b |
operator.mul(a,b) | a*b |
operator.lt(a,b) | a<b |
operator.le(a,b) | a<=b |
operator.eq(a,b) | a==b |
operator.ne(a,b) | a!=b |
operator.ge(a,b) | a>=b |
operator.gt(a,b) | a>b |
etc. | 等等 |
>>> import operator
>>> from functools import reduce
>>>
>>> operator.add(1,2)
3
>>> reduce(operator.add,range(100))#累加
4950
>>> reduce(operator.mul,range(1,7))#阶乘6!
720