Recursive function that returns combinations of size n chosen from list

我与影子孤独终老i 提交于 2021-01-29 05:13:37

问题


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:

  1. 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)?

  2. What should my recursive call look like?

  3. 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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!