组合函数与函数模块
Python 3.2 的文档提到了Collin Winter 的 functional
模块,这个模块里有一个叫 compose
的函数:
compose() 函数实现了函数组合。简单来说,它的作用是把一个函数的输出直接作为另一个函数的输入。
不过,这个模块自2006年7月以来就没有更新了,我在想有没有其他的替代方案。
目前,我只需要 compose
这个函数。请问下面这个原始的 functional.compose
定义在 Python 3 中还好用吗?
def compose(func_1, func_2, unpack=False):
"""
compose(func_1, func_2, unpack=False) -> function
The function returned by compose is a composition of func_1 and func_2.
That is, compose(func_1, func_2)(5) == func_1(func_2(5))
"""
if not callable(func_1):
raise TypeError("First argument to compose must be callable")
if not callable(func_2):
raise TypeError("Second argument to compose must be callable")
if unpack:
def composition(*args, **kwargs):
return func_1(*func_2(*args, **kwargs))
else:
def composition(*args, **kwargs):
return func_1(func_2(*args, **kwargs))
return composition
这个SO 问题有点相关;它在问 Python 是否应该支持 compose
的特殊语法。
1 个回答
6
你实现的 compose
在 Python 3.2 中是有效的,正如上面的评论所讨论的那样。
你提到的库中的大部分函数在 Python 中都有对应的实现,可以在文档中找到。
像 map
和 filter
这样的函数在 Python 中已经实现,并且可以用列表推导式简单表示。Python 还有一个 id
函数,可以返回对象的身份(以整数形式),而库中的 id
函数可以用 lambda x: x
来表示。
你可能会对 itertools
和 functools
模块感兴趣,它们包含了 partial
和 reduce
函数(reduce
类似于 foldl
,但参数的顺序不同)。
这里有一些我在标准库中没有找到的简单实现:
from functools import reduce
def flip(f):
if not callable(f):
raise TypeError("Cannot filp a non-callable object")
def result(*args, **kw):
args = list(args)
args.reverse()
return f(*args, **kw)
return result
def ilast(i):
return reduce(lambda _, x: x, i)
def iscanl(f, v, seq):
yield v
for a in seq:
v = f(v, a)
yield v
def scanl(*args, **kw):
return list(iscanl(*args, **kw))
def foldl(*args, **kw):
return ilast(iscanl(*args, **kw))
# Or using reduce
#def foldl(f, v, seq):
# return reduce(f, seq, v)
def iscanr_reverse(f, v, seq):
return iscanl(flip(f), v, seq)
def scanr(*args, **kw):
result = list(iscanr_reverse(*args, **kw))
result.reverse()
return result
def foldr(*args, **kw):
return ilast(iscanr_reverse(*args, **kw))