Search code examples
pythonrecursionreturn

Store output of a recursive function


I wrote a recursive function to get all the possible combinations of a given list. Below is the code.

It takes a list argument and prints all possible combinations.

def getCombinations(a):
    a2 = []
    ans = ['' for i in range(len(a))]
    helper(a,ans,0)

def helper(a,ans,i):
    if i == len(ans):
        print (ans)
    else:
        ans[i] = ''
        helper(a,ans,i+1)
        ans[i] = a[i]
        helper(a,ans,i+1)

So If we call getCombinations([1,2,3]), it prints as below:

['', '', '']
['', '', 3]
['', 2, '']
['', 2, 3]
[1, '', '']
[1, '', 3]
[1, 2, '']
[1, 2, 3]

My question is how do I store the above result in a list. I have tried to look for solution, and I know the issue is function doesn't technically return anything, but even if I try replacing return with print(...) it doesn't work as expected and returns nothing.


Solution

  • There's many ways to do this, but starting from your code, it's probably easiest to turn your function into a generator.

    A generator doesn't return the whole result in one go, but each element as it becomes available. That way, you can replace your print with a yield and collect everything in a single list by wrapping the call to helper(a,ans,0) in a list().

    However, since your code modifies the existing answer, you need to collect copies of the list, not the list itself, since that will change in later iterations.

    So:

    from copy import copy
    
    def getCombinations(a):
        ans = ['' for i in range(len(a))]
        return list(helper(a,ans,0))
    
    def helper(a,ans,i):
        if i == len(ans):
            yield copy(ans)
        else:
            ans[i] = ''
            yield from helper(a,ans,i+1)
            ans[i] = a[i]
            yield from helper(a,ans,i+1)
    
    print(getCombinations([1,2,3]))
    

    It's a very complicated way to do this though and very messy with the empty strings - why not use the standard libraries:

    from itertools import combinations
    print([c for n in range(4) for c in combinations([1, 2, 3], n)])
    

    Or, more generically, for any list:

    from itertools import combinations
    def all_combinations(a):
        return([c for n in range(len(a)+1) for c in combinations(a, n)])
    print(all_combinations([1, 2, 3]))