Reputation: 720
I have this code which takes a list of numbers and groups together all those that add up to 21. My problem is that in the end I want the numbers to all be lists in a list, but I am having trouble achieving that. Any advise would be appreciated
def twentyone(seq, groups = []):
goal = 21
s = sum(groups)
final = []
if s == goal:
final.append(groups)
print (final)
if s >= goal:
return
for i in range(len(seq)):
n = seq[i]
remaining = seq[i+1:]
twentyone(remaining, groups + [n])
#
seq = [1, 5, 6, 7, 10, 2, 11]
(twentyone(seq))
current output is:
[[1, 5, 6, 7, 2]]
[[1, 7, 2, 11]]
[[5, 6, 10]]
[[10, 11]]
I want the output to be:
[[1, 5, 6, 7, 2], [1, 7, 2, 11], [5, 6, 10], [10, 11]]
Upvotes: 1
Views: 60
Reputation: 5275
You are creating new final
list each time when it recursively calls itself. You just have to pass it as a default argument.
def twentyone(seq, groups = [], final = []): #default final list
goal = 21
s = sum(groups)
if s == goal:
final.append(groups)
if s >= goal:
return
for i in range(len(seq)):
n = seq[i]
remaining = seq[i+1:]
twentyone(remaining, groups + [n])
return final
seq = [1, 5, 6, 7, 10, 2, 11]
print twentyone(seq)
Results:-
[[1, 5, 6, 7, 2], [1, 7, 2, 11], [5, 6, 10], [10, 11]]
But the above solution will cause the final list grow each time twentyone
function will be called. So we can create a new final
list only for the first time it is called using first_call
flag as follows:
def twentyone(seq, groups = None, final = None, first_call=True):
if not groups:
groups = []
if first_call:
final = []
goal = 21
s = sum(groups)
if s == goal:
final.append(groups)
if s >= goal:
return
for i in range(len(seq)):
n = seq[i]
remaining = seq[i+1:]
twentyone(remaining, groups + [n], final, False)
return final
seq = [1, 5, 6, 7, 10, 2, 11]
print twentyone(seq)
print twentyone(seq)
Yields:
[[1, 5, 6, 7, 2], [1, 7, 2, 11], [5, 6, 10], [10, 11]]
[[1, 5, 6, 7, 2], [1, 7, 2, 11], [5, 6, 10], [10, 11]]
Upvotes: 2
Reputation: 1580
extending on Tanveers answer (which is the best approach in my opinion), you could also move the final variable outside or even use a static variable. The main problem in your code is that you are creating new final variable in each recursive call. These code below fixes that.
Local variable approach:
final = []
def twentyone(seq, groups = []):
goal = 21
s = sum(groups)
if s == goal:
final.append(groups)
if s >= goal:
return
for i in range(len(seq)):
n = seq[i]
remaining = seq[i+1:]
twentyone(remaining, groups + [n])
seq = [1, 5, 6, 7, 10, 2, 11]
twentyone(seq)
print (final)
Static variable approach:
class myfinal:
final=[]
def twentyone(seq, groups = []):
goal = 21
s = sum(groups)
if s == goal:
myfinal.final.append(groups)
if s >= goal:
return
for i in range(len(seq)):
n = seq[i]
remaining = seq[i+1:]
twentyone(remaining, groups + [n])
seq = [1, 5, 6, 7, 10, 2, 11]
twentyone(seq)
print (myfinal.final)
Upvotes: 0