I have a list of unique elements, let's say [1,2], and I want to split it onto k=2 sublists. Now I want to have all possible sublists:
[ [ [1,2],[] ], [ [1],[2] ], [ [2],[1] ], [ [],[1,2] ] ]
And I want to split onto 1<=k<=n sublists, so for k=1 it will be:
[ [1, 2] ]
How can I do that with Python 3?
UPDATE: my goal is to get all possible partitions of list of N unique numbers, where each partition will have k sublists. I would like to show better example than I have shown upper, I hope I will not miss something. So for list [1, 2, 3] and for k=2 I want to have next list:
[
[ [1,2,3], [] ],
[ [2,3], [1] ],
[ [1,3], [2] ],
[ [1,2], [3] ],
[ [1], [2,3] ],
[ [2], [1,3] ],
[ [3], [2,3] ],
[ [], [1,2,3] ]
]
UPDATE 2: so far I have combined two suggestions and little modification got next code:
def sorted_k_partitions(seq, k):
"""Returns a list of all unique k-partitions of `seq`.
Each partition is a list of parts, and each part is a tuple.
The parts in each individual partition will be sorted in shortlex
order (i.e., by length first, then lexicographically).
The overall list of partitions will then be sorted by the length
of their first part, the length of their second part, ...,
the length of their last part, and then lexicographically.
"""
n = len(seq)
groups = [] # a list of lists, currently empty
def generate_partitions(i):
if i >= n:
yield list(map(tuple, groups))
else:
if n - i > k - len(groups):
for group in groups:
group.append(seq[i])
yield from generate_partitions(i + 1)
group.pop()
if len(groups) < k:
groups.append([seq[i]])
yield from generate_partitions(i + 1)
groups.pop()
result = generate_partitions(0)
# Sort the parts in each partition in shortlex order
result = [sorted(ps, key = lambda p: (len(p), p)) for ps in result]
# Sort partitions by the length of each part, then lexicographically.
result = sorted(result, key = lambda ps: (*map(len, ps), ps))
return result
With this function I can do next:
import itertools as it
k=2
S = [1, 2, 3]
for i in (range(k)):
for groups in sorted_k_partitions(S, k-i):
for perm in it.permutations(groups+[tuple() for j in range(i)]):
print(perm)
The output is:
((1,), (2, 3))
((2, 3), (1,))
((2,), (1, 3))
((1, 3), (2,))
((3,), (1, 2))
((1, 2), (3,))
((1, 2, 3), ())
((), (1, 2, 3))
I'm not sure yet, that this code gives me right solution, maybe there is other way?