问题
I am trying to write a recursive function which takes as its inputs an integer n
, and a list l
, and returns a list of all the combinations of size n that can be chosen from the elements in l
. I'm aware that I can just use itertools, but I want to become better at writing recursive functions, and I believe writing my own function will help me.
So for example, if you input:
n = 3
l = [1, 2, 3, 4]
I want the output to be:
`[ [1, 2, 3], [1, 3, 4], [2, 3, 4], [1, 2, 4] ]
So far I've written this code:
def get_combinations(l, n): # returns the possible combinations of size n from a list of chars
if len(l) == 0:
return []
elif n == 1:
return [l[0]]
newList = list()
for i in range(len(l)):
sliced_list = l[i:]
m = n - 1
#lost here, believe I need to make a recursive call somewhere with get_combinations(sliced_list, m)
return newList
I found this example of such a function for permutations helpful, but I'm struggling to implement something similar.
To clarify, I set up my base cases in the way I did because I'm expecting to pass sliced_list
and m
in my recursive call, and if you imagine the situation when i = 3
, you'll have an empty list for sliced_list
, and m
will be 1 when you've gone deep enough to build up a combination. But I'm not married to these base cases.
Let me try to summarize the questions I have:
How do I produce a final result which is exactly a list of lists, instead of a list of lists of lists of lists ... (depth = n)?
What should my recursive call look like?
Am I going about this problem in exactly the wrong way?
回答1:
First I would recommend that you layout your function like:
def get_combinations(array, n):
solutions = []
# all the code goes here
return solutions
That way if there's a case that's a problem, like n == 0
, you can just ignore it and get a valid (empty) result. The next issue is this line is wrong:
elif n == 1:
return [array[0]]
The correct thing to do if n == 1
is to return an array with every element of the array wrapped in a list
:
if n == 1:
solutions = [[element] for element in array]
This is your base case as the next layer up in the recursion will build on this. What comes next is the heart of the problem. If n > 1
and the array has content, then we need to loop over the indexes of the array. For each we'll call ourself recursively on everything past the current index and n - 1
:
sub_solutions = get_combinations(array[index + 1:], n - 1)
This returns partial solutions. We need to stuff the element at the current index, ie. array[index]
, onto the front of each sub_solution
in sub_solutions
, and add each augmented sub_solution
to our list of solutions
that we return at the end of the function:
solutions.append([array[index]] + sub_solution)
And that's it!
来源:https://stackoverflow.com/questions/55877039/recursive-function-that-returns-combinations-of-size-n-chosen-from-list