I wanted to write a recursive function that takes a variable number of arguments (each argument being an iterable list or set) and returns a set of all concatenated combinations of each argument. I learned how to write functions with a variable number of arguments and I know how to write recursive functions, but I don't know how to put those two together in Python (or if it is even possible).
Here's my code:
def generate_combinations( *args ):
# returns all combinations of each of the arguments
if len( args ) == 1:
return set( args[0] )
result = set()
lastdigits = generate_combinations( args[1:] )
for d in args[0]:
result.add( d + lastdigits )
if __name__ == '__main__':
lastDigit = [ '1', '2', '3' ]
allDigits = [ '4', '5' ]
print("{}".format( generate_combinations( allDigits, lastDigit )))
Expected output:
14
15
24
25
34
35
The "problem" with my code lies in line 7: lastdigits = generate_combinations( args[1:] )
. What I wanted to do here, is to pass all original arguments except the first one to the function (thus creating the recursion). And this is obviously not the way to do that. My question: can this be done, and how?
Ps: I know I can accomplish the same using a list of lists with one argument, but I'm curious is this is at all possible.
The requested job is done by these lines :
args = list(args)
args.pop(0)
recursiveCall( *tuple(args) )
Here the implementation of your function was a little buggy ( or I misunderstand your use of set maybe ).
def generate_combinations( *args, **kwargs ):
print("called with", args)
#terminate recursion
if len(args) == 1:
return list(set(args[0]))
#recursion
else:
result = []
args = list(args)
heads = args.pop(0)
tails = generate_combinations( *args, **kwargs )
for head in heads:
for tail in tails:
result.append(head + tail)
return result
if __name__ == '__main__':
allDigits = [ '1', '2', '3' ]
lastDigit = [ '4', '5' ]
letters = [ 'a', 'b' ]
print("{}".format( generate_combinations( allDigits, lastDigit, letters , Useless='parameter')))
Execution give :
['14a', '14b', '15a', '15b', '24a', '24b', '25a', '25b', '34a', '34b', '35a', '35b']
Hope you enjoy this ;)
Arthur.