Spliting a list into n uneven buckets with all combinations

Question:

I have a list like:

lst = [1,2,3,4,5,6,7,8,9,10]

and I want to get the combination of all splits for a given n bucket without changing the order of the list. Output exp for n=3:

[
 [1],[2],[3,4,5,6,7,8,9,10],
 [1],[2,3],[4,5,6,7,8,9,10],
 [1],[2,3,4],[5,6,7,8,9,10],
 .
 .
 .
 [1,2,3,4,5,6,7,8],[9],[10],
]

Python is the language I use but if you can direct me to an algorithm that would nice as well. I see this problem is usually apllied on strings. But couldn’t figure it out on the list.

P.S. this is my first question. Any feedback is appreciated on how to improve the question.

Asked By: Poyraz Tahan

||

Answers:

Try:

from itertools import product


def generate(n, l):
    for c in product(range(1, l), repeat=n - 1):
        s = sum(c)
        if s > l - 1:
            continue
        yield *c, l - s


lst = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
n = 3

for groups in generate(n, len(lst)):
    l, out = lst, []
    for g in groups:
        out.append(l[:g])
        l = l[g:]
    print(out)

Prints:

[[1], [2], [3, 4, 5, 6, 7, 8, 9, 10]]
[[1], [2, 3], [4, 5, 6, 7, 8, 9, 10]]
[[1], [2, 3, 4], [5, 6, 7, 8, 9, 10]]
[[1], [2, 3, 4, 5], [6, 7, 8, 9, 10]]
[[1], [2, 3, 4, 5, 6], [7, 8, 9, 10]]
[[1], [2, 3, 4, 5, 6, 7], [8, 9, 10]]
[[1], [2, 3, 4, 5, 6, 7, 8], [9, 10]]
[[1], [2, 3, 4, 5, 6, 7, 8, 9], [10]]
[[1, 2], [3], [4, 5, 6, 7, 8, 9, 10]]
[[1, 2], [3, 4], [5, 6, 7, 8, 9, 10]]
[[1, 2], [3, 4, 5], [6, 7, 8, 9, 10]]
[[1, 2], [3, 4, 5, 6], [7, 8, 9, 10]]
[[1, 2], [3, 4, 5, 6, 7], [8, 9, 10]]
[[1, 2], [3, 4, 5, 6, 7, 8], [9, 10]]
[[1, 2], [3, 4, 5, 6, 7, 8, 9], [10]]
[[1, 2, 3], [4], [5, 6, 7, 8, 9, 10]]
[[1, 2, 3], [4, 5], [6, 7, 8, 9, 10]]
[[1, 2, 3], [4, 5, 6], [7, 8, 9, 10]]
[[1, 2, 3], [4, 5, 6, 7], [8, 9, 10]]
[[1, 2, 3], [4, 5, 6, 7, 8], [9, 10]]
[[1, 2, 3], [4, 5, 6, 7, 8, 9], [10]]
[[1, 2, 3, 4], [5], [6, 7, 8, 9, 10]]
[[1, 2, 3, 4], [5, 6], [7, 8, 9, 10]]
[[1, 2, 3, 4], [5, 6, 7], [8, 9, 10]]
[[1, 2, 3, 4], [5, 6, 7, 8], [9, 10]]
[[1, 2, 3, 4], [5, 6, 7, 8, 9], [10]]
[[1, 2, 3, 4, 5], [6], [7, 8, 9, 10]]
[[1, 2, 3, 4, 5], [6, 7], [8, 9, 10]]
[[1, 2, 3, 4, 5], [6, 7, 8], [9, 10]]
[[1, 2, 3, 4, 5], [6, 7, 8, 9], [10]]
[[1, 2, 3, 4, 5, 6], [7], [8, 9, 10]]
[[1, 2, 3, 4, 5, 6], [7, 8], [9, 10]]
[[1, 2, 3, 4, 5, 6], [7, 8, 9], [10]]
[[1, 2, 3, 4, 5, 6, 7], [8], [9, 10]]
[[1, 2, 3, 4, 5, 6, 7], [8, 9], [10]]
[[1, 2, 3, 4, 5, 6, 7, 8], [9], [10]]
Answered By: Andrej Kesely

For a manual implementation, you could use a recursive generator function:

def parts(lst, n):
    if 0 < n <= len(lst):
        if n == 1:
            yield [lst]
        else:
            for i in range(1, len(lst)-n+2):
                for part in parts(lst[i:], n-1):
                    yield [lst[:i]] + part



pprint(list(parts([1,2,3,4], 3)))
# [[[1], [2], [3, 4]], 
#  [[1], [2, 3], [4]], 
#  [[1, 2], [3], [4]]]
pprint(list(parts([1,2,3,4,5,6], 3)))
# [[[1], [2], [3, 4, 5, 6]],
#  [[1], [2, 3], [4, 5, 6]],
#  [[1], [2, 3, 4], [5, 6]],
#  [[1], [2, 3, 4, 5], [6]],
#  [[1, 2], [3], [4, 5, 6]],
#  [[1, 2], [3, 4], [5, 6]],
#  [[1, 2], [3, 4, 5], [6]],
#  [[1, 2, 3], [4], [5, 6]],
#  [[1, 2, 3], [4, 5], [6]],
#  [[1, 2, 3, 4], [5], [6]]]
Answered By: user2390182

A slightly shorter recursive approach:

lst, n = [1,2,3,4,5,6,7,8,9,10], 3
def group(d, c = []):
   if not d and len(c) == n:
      yield c
   if d and c:
       yield from group(d[1:], c[:-1]+[c[-1]+[d[0]]])
   if d and len(c) < n:
       yield from group(d[1:], c+[[d[0]]])

print(list(group(lst)))

Output:

[[[1, 2, 3, 4, 5, 6, 7, 8], [9], [10]],
 [[1, 2, 3, 4, 5, 6, 7], [8, 9], [10]],
 [[1, 2, 3, 4, 5, 6, 7], [8], [9, 10]],
 [[1, 2, 3, 4, 5, 6], [7, 8, 9], [10]],
 [[1, 2, 3, 4, 5, 6], [7, 8], [9, 10]],
 [[1, 2, 3, 4, 5, 6], [7], [8, 9, 10]],
 [[1, 2, 3, 4, 5], [6, 7, 8, 9], [10]],
 [[1, 2, 3, 4, 5], [6, 7, 8], [9, 10]],
 [[1, 2, 3, 4, 5], [6, 7], [8, 9, 10]],
 [[1, 2, 3, 4, 5], [6], [7, 8, 9, 10]],
 [[1, 2, 3, 4], [5, 6, 7, 8, 9], [10]],
 [[1, 2, 3, 4], [5, 6, 7, 8], [9, 10]],
 [[1, 2, 3, 4], [5, 6, 7], [8, 9, 10]],
 [[1, 2, 3, 4], [5, 6], [7, 8, 9, 10]],
 [[1, 2, 3, 4], [5], [6, 7, 8, 9, 10]],
 [[1, 2, 3], [4, 5, 6, 7, 8, 9], [10]],
 [[1, 2, 3], [4, 5, 6, 7, 8], [9, 10]],
 [[1, 2, 3], [4, 5, 6, 7], [8, 9, 10]],
 [[1, 2, 3], [4, 5, 6], [7, 8, 9, 10]],
 [[1, 2, 3], [4, 5], [6, 7, 8, 9, 10]],
 [[1, 2, 3], [4], [5, 6, 7, 8, 9, 10]],
 [[1, 2], [3, 4, 5, 6, 7, 8, 9], [10]],
 [[1, 2], [3, 4, 5, 6, 7, 8], [9, 10]],
 [[1, 2], [3, 4, 5, 6, 7], [8, 9, 10]],
 [[1, 2], [3, 4, 5, 6], [7, 8, 9, 10]],
 [[1, 2], [3, 4, 5], [6, 7, 8, 9, 10]],
 [[1, 2], [3, 4], [5, 6, 7, 8, 9, 10]],
 [[1, 2], [3], [4, 5, 6, 7, 8, 9, 10]],
 [[1], [2, 3, 4, 5, 6, 7, 8, 9], [10]],
 [[1], [2, 3, 4, 5, 6, 7, 8], [9, 10]],
 [[1], [2, 3, 4, 5, 6, 7], [8, 9, 10]],
 [[1], [2, 3, 4, 5, 6], [7, 8, 9, 10]],
 [[1], [2, 3, 4, 5], [6, 7, 8, 9, 10]],
 [[1], [2, 3, 4], [5, 6, 7, 8, 9, 10]],
 [[1], [2, 3], [4, 5, 6, 7, 8, 9, 10]],
 [[1], [2], [3, 4, 5, 6, 7, 8, 9, 10]]]
Answered By: Ajax1234
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.