在Python中等效Haskell"until"

Rya*_*cus 0 python haskell functional-programming

在Python中是否有任何与Haskelluntil函数相同的内置函数?

从本质上讲,until应用一个函数f来提供一个初始值v,然后应用ff(v),直到满足条件.换句话说,until返回重复应用的结果f直到条件成立.

我可以在Python中实现这一点,如下所示:

def until(cond, func, starting):
    val = starting
    while not cond(val):
        val = func(val)
    return val
Run Code Online (Sandbox Code Playgroud)

我应该使用这个实现,还是应该使用一些库函数?

Bak*_*riu 5

不,没有相当于的内置功能until.Python的内置和itertools模块从Haskell中获取了许多东西,但不是until函数.你的也可能是实现它的最简单,最有效的方法.

实际上真正的问题是没有函数返回应用f迭代函数的结果,所以你不得不编写iter_apply函数来做到这一点.

实现iter_apply它时,很容易编写一些内置函数来获取until:

#from itertools import ifilter as filter  # in python2

def iter_apply(func, value):
    while True:
        yield value
        value = func(value)

def until2(cond, func, starting):
    return next(filter(cond, iter_apply(func, starting)))

# or:

from itertools import dropwhile
def until3(cond, func, starting):
    iterated_values = iter_apply(func, starting)
    return next(dropwhile(lambda x: not cond(x), iterated_values))
Run Code Online (Sandbox Code Playgroud)

时差:

In [12]: %timeit until(lambda x: x > 10000, lambda x: x+1, 0)
100 loops, best of 3: 2.33 ms per loop

In [13]: %timeit until2(lambda x: x > 10000, lambda x: x+1, 0)
100 loops, best of 3: 2.45 ms per loop

In [14]: %timeit until3(lambda x: x > 10000, lambda x: x+1, 0)
100 loops, best of 3: 3.81 ms per loop
Run Code Online (Sandbox Code Playgroud)