理解toolz用例

时间:2017-05-24 05:47:48

标签: python functional-programming toolz

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

1 个答案:

答案 0 :(得分:6)

  • composethread_*pipe

    compose基本上是function compostion(∘)。它的主要目标是将不同的功能组合到可重用块中。与参数的顺序相比,应用程序的顺序是相反的,因此compose(f, g, h)(x)f(g(h(x)))(与(f∘g)(x)相同的是 f(g(x) ))。

    thread_*pipe是关于使用可重用块来创建单个数据流。只能使用延迟操作来执行执行,但是块是固定的。申请顺序与参数顺序相同,因此pipe(x, f, g, h)h(g(f(x)))

  • compose vs thread_*

    compose不允许其他参数,而thread_*则允许。没有currying compose只能用于一元函数。

    thread_相比,可以使用更高级别的函数,包括常用的高阶函数:

    thread_last(
        range(10),
        (map, lambda x: x + 1),
        (filter, lambda x: x % 2 == 0)
    )
    

    compose相同的事情,你需要讨论:

    pipe(
        range(10), 
        lambda xs: map(lambda x: x + 1, xs), 
        lambda xs: filter(lambda x: x % 2 == 0, xs)
    )
    

    from toolz import curried
    
    pipe(
        range(10), 
        curried.map(lambda x: x + 1), 
        curried.filter(lambda x: x % 2 == 0)
    )
    
  • 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
    

在实践中(忽略一些形式主义)这些功能通常是可以互换的,特别是当与functools.partial / toolz.curry和一些lambda表达式结合使用时,但根据上下文,它只是更多方便一个人使用另一个。

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