I have been working on generating all possible submodels for a biological problem. I have a working recursion for generating a big list of all the submodels I want. However, the lists get unmanageably large pretty fast (N=12 is just possible in the example below, N>12 uses too much memory). So I wanted to convert it to a generator function using yield instead, but I'm stuck.
My working recursive function looks like this:
def submodel_list(result, pat, current, maxn):''' result is a list to append topat is the current pattern (starts as empty list)current is the current number of the patternmaxn is the number of items in the pattern'''if pat:curmax = max(pat)else: curmax = 0for 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)
That gives me the expected list of submodels for my purposes.
Now, I want to get that same list using a recursion. Naively, I thought I could just switch out my result.append() for a yield function, and the rest would work OK. So I tried this:
def submodel_generator(pat, current, maxn):'''same as submodel_list but yields instead'''if pat:curmax = max(pat)else: curmax = 0for i in range(current):print i, current, maxnif i-1 <= curmax:print curmaxnewpat = pat[:]newpat.append(i)if current == maxn:yield newpatelse:submodel_generator(newpat, current+1, maxn)b = submodel_generator([], 1, 5)
for model in b: print model
But now I get nothing. A (very dumb) bit of digging tells me the function gets to the final else statement once, then stops - i.e. the recursion no longer works.
Is there a way to turn my first, clunky, list-making function into a nice neat generator function? Is there something silly I've missed here? All help hugely appreciated!