Python 是否具有用于一阶递归关系的迭代递归生成器函数?
Does Python have an iterative recursion generator function for first-order recurrence relations?
是否有大致相当于
的内置函数或标准库函数
def recur_until(start, step_fu, stop_predicate=lambda _: False):
current = start
while not stop_predicate(current):
yield current
current = step_fu(current)
或
def recur_while(start, step_fu, predicate=lambda _: True):
current = start
while predicate(current):
yield current
current = step_fu(current)
甚至只是
def recur(start, step_fu):
current = start
while True:
yield current
current = step_fu(current)
在 Python 的任何版本中? (后者与 itertools.takewhile
组合时与其他两个一样好。)
像这样的生成器函数将允许迭代地计算某些递归定义的序列,即一阶递归关系。
虽然这些在需要时并不难实现,但我觉得它们应该是 itertools
or maybe functools
的一部分,但如果是的话,我没能在文档中找到它, 然而.
使用示例:
list(recur_until(2, lambda x: x**2 - 1, lambda x: x > 1e4))
# [2, 3, 8, 63, 3968]
也应该使用非数字元素:
list(recur_until('', lambda x: '[{}]({})'.format(x, len(x)), lambda x: len(x) > 30))
# ['',
# '[](0)',
# '[[](0)](5)',
# '[[[](0)](5)](10)',
# '[[[[](0)](5)](10)](16)',
# '[[[[[](0)](5)](10)](16)](22)']
缺少的 link 是您需要将递归步进函数转换为生成器的东西。一旦你有了它,你就可以使用任何 itertools 方法。
def recur_to_gen(step_fu, current, sentinel=None):
while current != sentinel:
yield current
current = step_fu(current)
matches = itertools.takewhile(predicate, recur_to_gen(step_fu, start))
recur_to_gen
可能是建议添加到 itertools
.
的合理内容
functional 包提供了模拟这个的片段。
from functional import dropWhile, iterate
recur = dropWhile(predicate, iterate(step_func, start))
例如,
>>> next(dropWhile(lambda x : x < 10, iterate(lambda x: x + 1, 2)))
10
(dropWhile
与 itertools.dropwhile
并没有什么不同。)
在 Python 3.3+ 中,新的 itertools.accumulate
可以与其他 itertools
结合使用
例如:
>>> from itertools import accumulate, repeat, takewhile
>>> fun = accumulate(range(2, 10), lambda x, _: x**2 - 1)
>>> list(fun)
[2, 3, 8, 63, 3968, 15745023, 247905749270528, 61457260521381894004129398783]
>>> fun = takewhile(lambda y: y < 1e4, accumulate(repeat(2), lambda x, _: x**2 - 1))
>>> list(fun)
[2, 3, 8, 63, 3968]
accumulate
接受一个序列和一个带有 2 个参数的函数:第一个是累加值,第二个是序列中的下一个值。在这种情况下,我们只需要第一个参数,对于传递函数的第一次调用,它将是传递给 accumulate
的序列的第一个元素,对于后续调用,它将是该函数的 return 值。
因此,我们只需要将传递序列的开头作为我们的初始值——在本例中为 2
。序列其余部分的内容无关紧要,但我们可以使用它的长度来控制我们想要的元素数量(如第一个示例)或创建一个无限生成器(如第二个示例)。
是否有大致相当于
的内置函数或标准库函数def recur_until(start, step_fu, stop_predicate=lambda _: False):
current = start
while not stop_predicate(current):
yield current
current = step_fu(current)
或
def recur_while(start, step_fu, predicate=lambda _: True):
current = start
while predicate(current):
yield current
current = step_fu(current)
甚至只是
def recur(start, step_fu):
current = start
while True:
yield current
current = step_fu(current)
在 Python 的任何版本中? (后者与 itertools.takewhile
组合时与其他两个一样好。)
像这样的生成器函数将允许迭代地计算某些递归定义的序列,即一阶递归关系。
虽然这些在需要时并不难实现,但我觉得它们应该是 itertools
or maybe functools
的一部分,但如果是的话,我没能在文档中找到它, 然而.
使用示例:
list(recur_until(2, lambda x: x**2 - 1, lambda x: x > 1e4))
# [2, 3, 8, 63, 3968]
也应该使用非数字元素:
list(recur_until('', lambda x: '[{}]({})'.format(x, len(x)), lambda x: len(x) > 30))
# ['',
# '[](0)',
# '[[](0)](5)',
# '[[[](0)](5)](10)',
# '[[[[](0)](5)](10)](16)',
# '[[[[[](0)](5)](10)](16)](22)']
缺少的 link 是您需要将递归步进函数转换为生成器的东西。一旦你有了它,你就可以使用任何 itertools 方法。
def recur_to_gen(step_fu, current, sentinel=None):
while current != sentinel:
yield current
current = step_fu(current)
matches = itertools.takewhile(predicate, recur_to_gen(step_fu, start))
recur_to_gen
可能是建议添加到 itertools
.
functional 包提供了模拟这个的片段。
from functional import dropWhile, iterate
recur = dropWhile(predicate, iterate(step_func, start))
例如,
>>> next(dropWhile(lambda x : x < 10, iterate(lambda x: x + 1, 2)))
10
(dropWhile
与 itertools.dropwhile
并没有什么不同。)
在 Python 3.3+ 中,新的 itertools.accumulate
可以与其他 itertools
例如:
>>> from itertools import accumulate, repeat, takewhile
>>> fun = accumulate(range(2, 10), lambda x, _: x**2 - 1)
>>> list(fun)
[2, 3, 8, 63, 3968, 15745023, 247905749270528, 61457260521381894004129398783]
>>> fun = takewhile(lambda y: y < 1e4, accumulate(repeat(2), lambda x, _: x**2 - 1))
>>> list(fun)
[2, 3, 8, 63, 3968]
accumulate
接受一个序列和一个带有 2 个参数的函数:第一个是累加值,第二个是序列中的下一个值。在这种情况下,我们只需要第一个参数,对于传递函数的第一次调用,它将是传递给 accumulate
的序列的第一个元素,对于后续调用,它将是该函数的 return 值。
因此,我们只需要将传递序列的开头作为我们的初始值——在本例中为 2
。序列其余部分的内容无关紧要,但我们可以使用它的长度来控制我们想要的元素数量(如第一个示例)或创建一个无限生成器(如第二个示例)。