我一直在生成一个生物问题的所有可能子模型。我已经有了一个工作递归函数,可以生成我想要的所有子模型的大列表。然而,这些列表很快变得难以管理(在下面的示例中N = 12刚好可行,但N> 12会使用过多的内存)。所以我想将其转换为使用yield的发生器函数,但是我卡住了。
我的递归函数如下:
但现在我什么也得不到。通过(非常愚蠢的)挖掘,我发现该函数只有一次到达最终else语句,然后停止 - 即递归不再起作用。
是否有一种方法可以将我的第一个、笨拙的列表制作函数变成一个漂亮、整洁的生成器函数?我是否错过了什么傻乎乎的东西?非常感谢所有的帮助!
我的递归函数如下:
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函数替换我的result.append(),其余部分就可以正常工作。因此,我尝试了以下内容:
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语句,然后停止 - 即递归不再起作用。
是否有一种方法可以将我的第一个、笨拙的列表制作函数变成一个漂亮、整洁的生成器函数?我是否错过了什么傻乎乎的东西?非常感谢所有的帮助!
yield from submodel_generator(...)
。即将推出... - Dietrich Eppyield from
的酷之处在于,与for ... yield
不同的是,它可以正确处理生成器的.send()
和.throw()
方法。 - yak