理解toolz用例

Mal*_*umi 7 python functional-programming toolz

我正在学习一些函数式编程并查看toolz.compose,pipe,thread_first和thread_last之间的差异对我来说似乎非常微妙或根本不存在.这些功能的预期不同用例是什么?

hi-*_*zir 7

  • 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_firstthread_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表达式结合使用时,但是根据上下文,使用一个在另一个上面会更方便.

例如,内置高阶函数,如mapfunctools.reduce,thread_last是一个自然的选择.如果要在多个位置重用一段代码,最好使用而compose(h, g, f)不是添加函数包装器def fgh(x) pipe(x, f, g, h).等等.