00__00__00
00__00__00

Reputation: 5337

Splitting a list into all combinations

I am aware of many posts with the similar questions and have been through many of them. However, I am not able to do what I need.

I have list L=[0,1,2,3,4,5] which I want to split into a pair of tuples. For example:

[(0,1,2),(3,4,5)]
[(0,1,3),(2,4,5)]
[(0,1,4),(2,4,5)]
...

Each tuple needs to contain half of the elements from the original list (in this example 3 of 6). A solution needs to produce every combination of tuples using 3 elements.

I can easily find all the possible tuple within the list using

list(itertools.combinations(L, 3))

[(0, 1, 2), (0, 1, 3), (0, 1, 4), (0, 1, 5), (0, 2, 3), (0, 2, 4), ...]

Does itertools offers any workround for this as well?

Upvotes: 2

Views: 1466

Answers (1)

user2390182
user2390182

Reputation: 73470

There may be more performant solutions that avoid a complete extra iteration of the list for the other half, but that should be rather negligible:

l = [[x, tuple(y for y in L if y not in x)] for x in combinations(L, 3)]
[[(0, 1, 2), (3, 4, 5)],
 [(0, 1, 3), (2, 4, 5)],
 [(0, 1, 4), (2, 3, 5)],
 [(0, 1, 5), (2, 3, 4)],
 [(0, 2, 3), (1, 4, 5)],
 [(0, 2, 4), (1, 3, 5)],
 [(0, 2, 5), (1, 3, 4)],
 [(0, 3, 4), (1, 2, 5)],
 [(0, 3, 5), (1, 2, 4)],
 [(0, 4, 5), (1, 2, 3)],
 [(1, 2, 3), (0, 4, 5)],
 [(1, 2, 4), (0, 3, 5)],
 [(1, 2, 5), (0, 3, 4)],
 [(1, 3, 4), (0, 2, 5)],
 [(1, 3, 5), (0, 2, 4)],
 [(1, 4, 5), (0, 2, 3)],
 [(2, 3, 4), (0, 1, 5)],
 [(2, 3, 5), (0, 1, 4)],
 [(2, 4, 5), (0, 1, 3)],
 [(3, 4, 5), (0, 1, 2)]]

This depends on the absence of duplicates in the original list. Otherwise you'd have to work with the indexes instead. The following modification uses the same approach, but uses the list indexes for the combinations and can thus handle duplicates in the original list:

indexes = ((x, (y for y in L if y not in x)) for x in combinations(range(len(L)), 3))
l = [[tuple(L[a] for a in A), tuple(L[b] for b in B)] for A, B in indexes]

Upvotes: 5

Related Questions