Mal*_*umi 7 python functional-programming toolz
我正在学习一些函数式编程并查看toolz.compose,pipe,thread_first和thread_last之间的差异对我来说似乎非常微妙或根本不存在.这些功能的预期不同用例是什么?
composevs. thread_*和pipe
compose本质上是一个函数组合(∘).它的主要目标是将不同的功能组合成可重用的块.的顺序的应用程序相比,参数顺序相反,从而compose(f, g, h)(x)是f(g(h(x)))(相同(F∘克)(X)是 F(G(X)) ).
thread_*并且pipe是关于使用可重用块来创建单个数据流.只能使用延迟操作来执行执行,但是块是固定的.应用程序的顺序是一样的参数顺序,以便pipe(x, f, g, h)为h(g(f(x))).
composeVS thread_*.
compose同时不允许其他参数thread_*.没有currying compose只能用于一元功能.
相比之下,thread_可以使用更高级的功能,包括常用的高阶函数:
thread_last(
range(10),
(map, lambda x: x + 1),
(filter, lambda x: x % 2 == 0)
)
Run Code Online (Sandbox Code Playgroud)
同样的事情,compose你需要currying:
pipe(
range(10),
lambda xs: map(lambda x: x + 1, xs),
lambda xs: filter(lambda x: x % 2 == 0, xs)
)
Run Code Online (Sandbox Code Playgroud)
要么
from toolz import curried
pipe(
range(10),
curried.map(lambda x: x + 1),
curried.filter(lambda x: x % 2 == 0)
)
Run Code Online (Sandbox Code Playgroud)thread_first与thread_last.
thread_first 将管道参数放在函数的第一个位置.
thread_last 将管道参数放在函数的最后位置.
例如
>>> from operator import pow
>>> thread_last(3, (pow, 2)) # pow(2, 3)
8
>>> thread_first(3, (pow, 2)) # pow(3, 2)
9
Run Code Online (Sandbox Code Playgroud)在实践中(忽略一些形式),这些函数通常是可以互换的,特别是当与functools.partial/ toolz.curry和某些lambda表达式结合使用时,但是根据上下文,使用一个在另一个上面会更方便.
例如,内置高阶函数,如map或functools.reduce,thread_last是一个自然的选择.如果要在多个位置重用一段代码,最好使用而compose(h, g, f)不是添加函数包装器def fgh(x) pipe(x, f, g, h).等等.