我一直致力于为生物问题生成所有可能的子模型。我有一个工作递归,用于生成我想要的所有子模型的大列表。但是,列表的速度非常快(N = 12只能在下面的示例中使用,N> 12使用太多内存)。所以我想用yield来转换为生成器函数,但是我被卡住了。
我的工作递归函数如下所示:
def submodel_list(result, pat, current, maxn):
''' result is a list to append to
pat is the current pattern (starts as empty list)
current is the current number of the pattern
maxn is the number of items in the pattern
'''
if pat:
curmax = max(pat)
else:
curmax = 0
for i in range(current):
if i-1 <= curmax:
newpat = pat[:]
newpat.append(i)
if current == maxn:
result.append(newpat)
else:
submodel_generator(result, newpat, current+1, maxn)
result = []
submodel_list(result, [], 1, 5)
这为我提供了预期的子模型列表。
现在,我希望使用递归获得相同的列表。天真的,我以为我可以将yield.append()转换为yield函数,其余的都可以正常工作。所以我尝试了这个:
def submodel_generator(pat, current, maxn):
'''same as submodel_list but yields instead'''
if pat:
curmax = max(pat)
else:
curmax = 0
for i in range(current):
print i, current, maxn
if i-1 <= curmax:
print curmax
newpat = pat[:]
newpat.append(i)
if current == maxn:
yield newpat
else:
submodel_generator(newpat, current+1, maxn)
b = submodel_generator([], 1, 5)
for model in b: print model
但现在我一无所获。一个(非常愚蠢的)挖掘告诉我函数一次到达最后的else语句,然后停止 - 即递归不再起作用。
有没有办法将我的第一个,笨重的列表制作功能变成一个漂亮的整齐的生成器功能?我在这里错过了什么傻事吗?所有的帮助非常感谢!
答案 0 :(得分:21)
你应该改变这个:
submodel_generator(newpat, current+1, maxn)
到此:
for b in submodel_generator(newpat, current+1, maxn):
yield b
这将递归地产生连续调用函数的值。
[更新]:请注意,从Python 3.3开始,您可以使用新的yield from语法:
yield from submodel_generator(newpat, current+1, maxn)