M. Barabas
M. Barabas

Reputation: 99

Skipping duplicated when generating combinations

I have this code:

from collections import Counter
def groups(d, l, c = []):
   if l == len(c):
     yield c
   else:
      for i in d:
         if i not in c:
            _c = Counter([j for k in [*c, i] for j in k])
            if all(j < 3 for j in _c.values()):
               yield from groups(d, l, c+[i])

data = [(1,2),(2,3),(2,4),(2,5),(2,6),(3,1),(3,2),(3,4)]
result = list(groups(data, 3))

This code is generating triples of pairs like this: [[(1, 2), (2, 3), (3, 1)], [(1, 2), (2, 3), (3, 4)], [(1, 2), (2, 4), (3, 1)],1[(1, 2), (2, 4), (3, 4)], [(1, 2), (2, 5), (3, 1)], [(1, 2), (2, 5), (3, 4)] ...

The problem is, that there are duplicates like this:

[(1, 2), (2, 3), (3, 1)] and [(2, 3), (1, 2), (3, 1)]

Is there a way how to avoid them in process of generating?

Upvotes: 0

Views: 43

Answers (1)

DeepSpace
DeepSpace

Reputation: 81604

You are reinventing the wheel. Simply use itertools.combinations:

from itertools import combinations

data = [(1, 2), (2, 3), (2, 4), (2, 5), (2, 6), (3, 1), (3, 2), (3, 4)]
print(list(combinations(data, 3)))
# [((1, 2), (2, 3), (2, 4)), ((1, 2), (2, 3), (2, 5)), ...

You can confirm that this does not have repetitions by checking the length of the returned list (which is 56), which is exactly what you would expect (8 choose 3 is 56)

If you need to apply custom logic you can still do that:

from itertools import combinations

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

wanted_combinations = []
for combination in combinations(data, 3):
    # apply logic
    if condition:
        wanted_combinations.append(combination)

Upvotes: 1

Related Questions