【发布时间】:2012-01-14 12:26:24
【问题描述】:
我一直致力于为生物学问题生成所有可能的子模型。我有一个工作递归来生成我想要的所有子模型的大列表。但是,列表很快变得难以管理(在下面的示例中 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)
这为我提供了预期的子模型列表。
现在,我想使用递归获得相同的列表。天真地,我以为我可以将我的 result.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 语句一次,然后停止 - 即递归不再起作用。
有没有办法将我的第一个笨重的列表制作函数变成一个漂亮整洁的生成器函数?我在这里错过了什么愚蠢的事情吗?非常感谢所有帮助!
【问题讨论】:
-
在 Python 3.3 中,您可以使用
yield from submodel_generator(...)。即将推出... -
@DietrichEpp,啊,被接受了吗?酷。
-
@senderle 我同意它在本质上与那篇文章非常相似,但不幸的是我在 Python 方面还不够好,无法理解是什么让那篇文章起作用,所以我想我无论如何都会发布我的类似示例,希望得到一些急需的帮助!
-
yield from的酷之处在于,它与for ... yield不同,它可以正确处理生成器的.send()和.throw()方法。
标签: python recursion generator