简体   繁体   English

在Python中相当于Haskell“直到”

[英]Equivalent of Haskell “until” in Python

Is there any built-in equivalent to Haskell's until function in Python? 在Python中是否有与Haskell的until函数等效的内置函数?

Essentially, until applies a function f to a provided starting value v , then applies f to f(v) , until a condition is met. 本质上, until将函数f应用于提供的起始值v until ,然后将f应用于f(v) ,直到满足条件为止。 In other words, until returns the result of repeatedly applying f until a condition holds. 换句话说, until返回直到条件成立为止,重复应用f的结果。

I can implement this in Python like so: 我可以这样在Python中实现:

def until(cond, func, starting):
    val = starting
    while not cond(val):
        val = func(val)
    return val

Should I use this implementation, or is there some library function I should be using instead? 我应该使用此实现,还是应该使用一些库函数呢?

No, there is no built-in function equivalent to until . 没有,没有内置的功能等同于until Python's built-in and itertools module has taken many things from Haskell, but not the until function. Python的内置和itertools模块从Haskell获得了很多东西,但没有until函数。 Yours is also probably the simplest and most efficient way to implement it. 您的解决方案可能也是最简单,最有效的方法。

In fact the real problem is that there is no function that returns the results of applying a function f iterated, so you somehow have to write the iter_apply function to do that. 其实真正的问题是,有没有函数,返回将函数的结果f迭代,所以你无论如何必须写iter_apply功能来做到这一点。

When you implement iter_apply it's quite easy to compose some built-in functions to obtain until : 当您实现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))

Time differences: 时差:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM