Полностью рекурсивная функция должна быть:
def permutations_comp_recursive(first, last, perms, i):
if len(first) == 0:
perms.append(last)
elif i == len(first):
pass
else:
permutations_comp_recursive(first, last, perms, i+1)
if first:
permutations_comp_recursive(
first[:i]+first[i+1:],
last + [first[i]],
perms, 0)
Для хорошей производительности я рекомендую numpy solutions .
Редактировать 1: Теперь следующее должно быть хвостово-рекурсивным, с использованием списочных представлений. Это использует workarount для хвостовой рекурсии в python (и последние 2 аргумента были опущены - результат передается как возвращаемое значение):
import itertools as it
class Recurse(Exception):
def __init__(self, *args, **kwargs):
self.args = args
self.kwargs = kwargs
def recurse(*args, **kwargs):
raise Recurse(*args, **kwargs)
def tail_recursive(f):
def decorated(*args, **kwargs):
while True:
try:
return f(*args, **kwargs)
except Recurse as r:
args = r.args
kwargs = r.kwargs
continue
return decorated
@tail_recursive
def permutations_tail_recursive(first, last, direct=False):
if len(first) == 0 or not all(first):
return last
else:
l = len(first[0]) if direct else len(first)
if last:
return recurse([fi[:i]+fi[i+1:] for fi, i in it.product(first, range(l))],
[last[j] + first[j][i] for j, i in it.product(range(len(last)), range(l))], True)
else:
return recurse([first[:i]+first[i+1:] for i in range(l)],
[first[i] for i in range(l)], True)
Это не оптимизировано и использует циклы. Я не уверен, что это и код без цикла выше могут быть объединены - может посмотреть на это снова.
Для этого приложения можно использовать itertools.permutations.