Sabor Sabor - 1 year ago 139
Python Question

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?

Answer Source

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]
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download