0

I want to build a recursive function that finds all the subsets of size 'k' of a given list with length n>=k>=0 and returns a list of those subsets.

example: if the input list is [1,2,3,4] and k = 2 then the function will return [[4,3],[2,4],[2,3],[1,4],[1,3],[1,2]]

notice that different arrangments of list is considered to be the same list.

I think that this kind of recursion should work:

return [lst[0]] + choose_sets(lst[1:],k-1)   ¬¬and¬¬   choose_sets(lst[1:],k)

where choose_sets(lst,k) is the function.

Meaning:

input : [1,2,3,4] , k=3

calls:

[1] + [2,3,4],k=2 and [2,3,4], k=3

and so on...

can anyone guide me as to how I should call those 2 recursive calls 'at the same time' ? and what should my 'exiting term' be?

Thanks.

11
  • 1
    Unless this is an exercise, just use itertools.combinations(). Commented Apr 25, 2013 at 18:20
  • 1
    Is this homework or for fun? Because if it is a real-life problem, there is a standard library function for that. Commented Apr 25, 2013 at 18:20
  • you call them sequentially Commented Apr 25, 2013 at 18:21
  • this is indeed homework, I cant use itertools. @KarolyHorvath : how can i call them sequentially? can you please be more specific. If i call one of them then the function will just exit and never get to the other "return". Commented Apr 25, 2013 at 18:21
  • What combinations does an empty list have? Commented Apr 25, 2013 at 18:29

2 Answers 2

2

Suppose you have a list of size n and you need all subsets of size k.
This is basically the same as:

For each element of the list, create a new list without the element,
in the new list, find all the subsets of size k-1 (this is the recursive call),
and add the remove element to all the lists.

Now... this solution will have repetitions, for example, in the example you gave, you'll get both [4, 1] and [1, 4]. But it can be changed a little so that it will not create duplicate results.

edit
to handle duplications

def choose_sets(l, k):
  if k == 0:
    return [[]]
  if len(l) == 0:
    return []
  l2 = l[1:]
  subsets = choose_sets(l2, k-1)
  for s in subsets:
    s.append(l[0])
  return subsets+ choose_sets(l2, k)
Sign up to request clarification or add additional context in comments.

3 Comments

isn't this horribly inefficient? to create lets say 50 new lists if there are 50 elements in the list and then recursive call it over and over again? plus, I dont understand how can i create all those lists exactly and in the end, how do i handle duplicates?
@user2263215 Recursion is rarely the most efficient method, but it is often the most elegant.
When I run this code I get this error: AttributeError: 'int' object has no attribute 'append
0
b = []

def abc(a,k):
    if len(a)==k:
        b.append(a)
        return b

    b.extend([a[:k-1]+[i] for i in a[k-1:]])    
    return abc(a[1:],k)


print abc([1,2,3,4,5],2)

3 Comments

You're using a global variable.
I didn't say that it's incorrect, it's just that global variables are bad practice.
This code doesn't return the correct answer for abc([1,2,3,4,5],2)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.