首页 > 解决方案 > 标准库中 python 中的“loop_while”谓词函数

问题描述

我的项目有一定的限制,我不能使用类似的语句/关键字while,所以我想知道在标准库中是否存在类似于以下代码示例的函数,例如functoolsitertools等等?

>>> # signature: loop_while(pred, g, f, *args, **kwargs)
>>> loop_while(lambda r: r != 0,  # predicate
...            lambda v: v - 1,  # modifier function
...            lambda: 5  # initial function
... )

哪里loop_while可以定义为大致类似于

def loop_while(pred, g, f, *args, **kwargs):
   res = f(*args, **kwargs)
   while pred(res):
       res = g(res)

这在功能上等同于:

n = 5
while n != 0:
    n -= 1

或者另一种解决方案是允许您在一行中执行谓词循环,例如[<expr> while <pred>]但使用任何可能的技巧。

标签: pythonfunctional-programming

解决方案


itertools模块(令人惊讶的是)没有为以下函数提供配方,它提供了一个由xg(x)g(g(x))等组成的迭代:

def iterate(g, x):
    yield x
    for y in iterate(g(x), g):
        yield y

(以上由 3rd-party 模块提供toolz.itertoolz。它的定义比我的更干净:

def iterate(g, x):
    while True:
        yield x
        x = g(x)

)

那么你的函数只是iterate和的组合itertools.takewhile

def loopwhile(pred, g, f, *args, **kwargs):
    for x in itertools.takewhile(pred, iterate(g, f(*args, **kwargs))):
        yield x

举个例子,

>>> list(loopwhile(lambda x: x < 1024, lambda x: x * 2, lambda: 1))
[1, 2, 4, 8, 16, 32, 64, 128, 256, 512]

上面的 Python 3 版本稍微简单一些:

def iterate(g, x):
    yield x
    yield from iterate(g, g(x))

def loopwhile(pred, g, f, *args, **kwargs):
    yield from takewhile(pred, iterate(g, f(*args, **kwargs)))

推荐阅读