1

I'm doing a program that inputs a series of numbers, and takes 6 of them to make different combinations of lottery numbers. When I create the different combinations, I want to remove duplicates, so that each combination is only printed once. This is what I want to happen:

combo_list = [1 2 3 4 5 6 7]

And the output should be:

1 2 3 4 5 6
1 2 3 4 5 7
1 2 3 4 6 7
1 2 3 5 6 7
1 2 4 5 6 7
1 3 4 5 6 7
2 3 4 5 6 7

The code I'm using is:

   final = []
    for sublist in combo_list:
        if sublist not in final:
            final.append(sublist)
    for item in final:
        item = (sorted(item, key=int))
        print (' '.join(str(n) for n in item))

However, I get an output with many duplicates when I use the code:

1 2 3 4 5 6
1 2 3 4 5 7
1 2 3 4 5 6
1 2 3 4 6 7
1 2 3 4 5 7
1 2 3 4 6 7
1 2 3 4 5 6
1 2 3 4 5 7
1 2 3 4 5 6
1 2 3 5 6 7
1 2 3 4 5 7
1 2 3 5 6 7
1 2 3 4 5 6
1 2 3 4 6 7
1 2 3 4 5 6
1 2 3 5 6 7
1 2 3 4 6 7
1 2 3 5 6 7
1 2 3 4 5 7
1 2 3 4 6 7
1 2 3 4 5 7
1 2 3 5 6 7
1 2 3 4 6 7
1 2 3 5 6 7
1 2 3 4 5 6
.
.
.

Any ideas on what I have to change for each of the combinations to only print once?

2
  • Your algorithm appears to be flawed - you aren't approaching the problem right. The number of combinations is known and python as the itertools library for dealing with this problem in a more efficient manner. Commented May 27, 2013 at 2:38
  • Think about whether you can modify your code to not generate the duplicates in the first place. Commented May 27, 2013 at 3:00

5 Answers 5

5

Use itertools.combinations() for this:

import itertools as it
ans = it.combinations([1, 2, 3, 4, 5, 6, 7], 6)

The result is as it should be:

list(ans)

=> [(1, 2, 3, 4, 5, 6), (1, 2, 3, 4, 5, 7),
    (1, 2, 3, 4, 6, 7), (1, 2, 3, 5, 6, 7),
    (1, 2, 4, 5, 6, 7), (1, 3, 4, 5, 6, 7),
    (2, 3, 4, 5, 6, 7)]

If you need to print the numbers afterwards it's easy:

for r in ans:
    print ' '.join(str(s) for s in r) 

=> 1 2 3 4 5 6
   1 2 3 4 5 7
   1 2 3 4 6 7
   1 2 3 5 6 7
   1 2 4 5 6 7
   1 3 4 5 6 7
   2 3 4 5 6 7
Sign up to request clarification or add additional context in comments.

3 Comments

This is very useful, but I should have clarified; I was required to use recursion to solve this problem (which I did), so the final step was to eliminate the duplicates. Is there any alternative to itertools functions?
@user1778344 in the code you posted you didn't use recursion. Anyway, if you want to remove duplicates from a list of lists, transform it into a set of tuples: set(tuple(x) for x in final)
@ÓscarLópez You may also make the numbers strings to begin with so you don't need to convert them later
0

If I understand your question, go ahead and try using the combinations function from the itertools module. In your case, you'll get:

>>> import itertools
>>> list(itertools.combinations([1,2,3,4,5,6,7],6)
[(1, 2, 3, 4, 5, 6)
(1, 2, 3, 4, 5, 7)
(1, 2, 3, 4, 6, 7)
(1, 2, 3, 5, 6, 7)
(1, 2, 4, 5, 6, 7)
(1, 3, 4, 5, 6, 7)
(2, 3, 4, 5, 6, 7)] 

which is what I think you want.

Remember that the output of the combinations function is a generator.

1 Comment

Also, if you're interested, the documentation for the combination function in itertools gives a pure Python implementation of this algorithm.
0

You can just take the source to itertools.combinations then:

def lotto(iterable, r):
    pool = tuple(iterable)
    n = len(pool)
    if r > n:
        return
    indices = range(r)
    yield tuple(pool[i] for i in indices)
    while True:
        for i in reversed(range(r)):
            if indices[i] != i + n - r:
                break
        else:
            return
        indices[i] += 1
        for j in range(i+1, r):
            indices[j] = indices[j-1] + 1
        yield tuple(pool[i] for i in indices)

print list(lotto([1, 2, 3, 4, 5, 6, 7], 6))   

2 Comments

OP stated that the solution has to be recursive (even though his solution isn't recursive)
Sorry, I abbreviated my code, as it was quite long. I just posted the final few steps in the main function. By that point, the combinations had already been created, recursively.
0

Based on your desire to simply remove the duplicates.. Use python set

   final = []
    for sublist in combo_list:
        if sublist not in final:
            final.append(sublist)
    for item in set(tuple(x) for x in final):
        item = (sorted(item, key=int))
        print (' '.join(str(n) for n in item))

But FWIW - why re-create the wheel use the @Óscar López answer ;)

HTH

1 Comment

Lists are not hashable. See the last comment in my answer: what OP would need to do in the last loop is for item in set(tuple(x) for x in final)
0
 comb_list= range(1, 8)
 rip_idx = 6
 for idx in range(len(comb_list)):
    final = comb_list[0:rip_idx -idx ] + comb_list[rip_idx- idx + 1: ]
    print final

A simple way to achieve it solve without any library

Comments

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.