Python: как создать функцию рекурсивного генератора

Я работал над созданием всех возможных подмоделей для биологической проблемы. У меня есть рабочая рекурсия для создания большого списка всех подмоделей, которые мне нужны. Однако списки довольно быстро становятся неуправляемо большими (в приведенном ниже примере возможно 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, а затем останавливается - т.е. рекурсия больше не работает.

Есть ли способ превратить мою первую неуклюжую функцию создания списков в красивую аккуратную функцию генератора? Что-то глупое, что я здесь пропустил? Любая помощь очень ценится!

5
задан roblanf 6 December 2011 в 22:24
поделиться