【发布时间】:2010-07-18 19:39:27
【问题描述】:
有没有办法让下面的代码工作?
add = lambda n: (yield n) or add(n+1)
(答案不需要是函数式的)
【问题讨论】:
-
你希望它做什么?
标签: python generator recursion
有没有办法让下面的代码工作?
add = lambda n: (yield n) or add(n+1)
(答案不需要是函数式的)
【问题讨论】:
标签: python generator recursion
def add(n):
yield n
for m in add(n+1):
yield m
使用递归生成器很容易构建复杂的回溯器:
def resolve(db, goals, cut_parent=0):
try:
head, tail = goals[0], goals[1:]
except IndexError:
yield {}
return
try:
predicate = (
deepcopy(clause)
for clause in db[head.name]
if len(clause) == len(head)
)
except KeyError:
return
trail = []
for clause in predicate:
try:
unify(head, clause, trail)
for each in resolve(db, clause.body, cut_parent + 1):
for each in resolve(db, tail, cut_parent):
yield head.subst
except UnificationFailed:
continue
except Cut, cut:
if cut.parent == cut_parent:
raise
break
finally:
restore(trail)
else:
if is_cut(head):
raise Cut(cut_parent)
...
for substitutions in resolve(db, query):
print substitutions
这是一个由递归生成器实现的 Prolog 引擎。 db 是一个表示 Prolog 事实和规则数据库的字典。 unify() 是为当前目标创建所有替换并将更改附加到跟踪的统一函数,以便以后可以撤消它们。 restore() 执行撤消操作,is_cut() 测试当前目标是否为 '!',以便我们进行分支修剪。
【讨论】:
我不确定“yield(n) 或 add(n+1)”的意图,但递归生成器肯定是可能的。您可能需要阅读下面的链接以了解可能的情况,尤其是标题为“递归生成器”的部分。
【讨论】:
在我看来,您的函数只是未绑定序列的其他表达式:
n, n+1, n+2,....
def add(x):
while True:
yield x
x+=1
for index in add(5):
if not index<100: break ## do equivalent of range(5,100)
print(index)
这不是递归的,但我认为这里不需要递归样式。
基于其他答案链接的递归版本,它有生成器调用生成器,但不是递归的:
from __future__ import generators
def range_from(n):
yield n
for i in range_from(n+1):
yield i
for i in range_from(5):
if not i<100: break ## until 100 (not including)
print i
【讨论】: