Is there an efficient way in Python to get all partitions of a list of size n
into two subsets of size n/2
? I want to get some iterative construct
Here's an itertools
-based generator that I think yields exactly the values you want.
def sub_lists(sequence):
all_but_first = set(sequence[1:])
for item in itertools.combinations(sequence[1:], len(sequence)//2 - 1):
yield [[sequence[0]] + list(item), list(all_but_first.difference(item))]
I avoid near-duplicate outputs in two ways as compared to a permutations
based approach in Suever's answer. First, I avoid yielding both [["a", "b"], ["c", "d"]]
and [["c", "d"], ["a", "b"]]
by forcing all the results to have the first value of the input sequence in the first sublist. I avoid yielding [["a", "b"], ["c", "d"]]
and [["a", "b"], ["d", "c"]]
by building the second sublist using set-subtraction.
Note that yielding nested tuples might be a little more natural than nested lists. To do that, just change the last line to:
yield (sequence[0],) + item, tuple(all_but_first.difference(item))