>我的项目有一定的限制,我不能使用像while
这样的语句/关键字,所以我想知道是否存在一个类似于标准库中以下代码示例的函数,即functools
、itertools
等?
>>> # 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>]
但使用任何可能的技巧。
itertools
模块(令人惊讶(没有为以下函数提供配方,该函数提供了一个由x
、g(x)
、g(g(x))
等组成的可迭代对象:
def iterate(g, x):
yield x
for y in iterate(g(x), g):
yield y
(以上由第三方模块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)))