You can do that recursively by combining a first part of length 1,2,3,... with the partitions in 3 of the rest (recursing to 2 and 1):
from itertools import combinations
def partCombo(L,N=4):
if N==1: yield [L]; return
for size in range(1,len(L)-N+2):
for combo in combinations(range(len(L)),size): # index combinations
part = list(L[i] for i in combo) # first part
remaining = list(L)
for i in reversed(combo): del remaining[i] # unused items
yield from ([part]+rest for rest in partCombo(remaining,N-1))
output:
aList = list("abcdefg")
for part in partCombo(aList):
print(part)
[['a'], ['b'], ['c'], ['d', 'e', 'f', 'g']]
[['a'], ['b'], ['d'], ['c', 'e', 'f', 'g']]
[['a'], ['b'], ['e'], ['c', 'd', 'f', 'g']]
[['a'], ['b'], ['f'], ['c', 'd', 'e', 'g']]
[['a'], ['b'], ['g'], ['c', 'd', 'e', 'f']]
[['a'], ['b'], ['c', 'd'], ['e', 'f', 'g']]
[['a'], ['b'], ['c', 'e'], ['d', 'f', 'g']]
[['a'], ['b'], ['c', 'f'], ['d', 'e', 'g']]
[['a'], ['b'], ['c', 'g'], ['d', 'e', 'f']]
[['a'], ['b'], ['d', 'e'], ['c', 'f', 'g']]
[['a'], ['b'], ['d', 'f'], ['c', 'e', 'g']]
[['a'], ['b'], ['d', 'g'], ['c', 'e', 'f']]
[['a'], ['b'], ['e', 'f'], ['c', 'd', 'g']]
[['a'], ['b'], ['e', 'g'], ['c', 'd', 'f']]
[['a'], ['b'], ['f', 'g'], ['c', 'd', 'e']]
[['a'], ['b'], ['c', 'd', 'e'], ['f', 'g']]
... and many more ... (total 8400)
For a list of 20 items, there will be 1,085,570,781,624 combinations.
from math import factorial
def countCombos(L,N=4):
if N==1: return 1
result = 0
for size in range(1,L-N+2):
c = factorial(L)//factorial(size)//factorial(L-size)
c *= countCombos(L-size,N-1)
result += c
return result
sum(1 for _ in partCombo("abcdefg")) # 8400
sum(1 for _ in partCombo("abcdefghij")) # 818520
countCombos(7) # 8400
countCombos(10) # 818520
countCombos(15) # 1016542800
countCombos(20) # 1085570781624
With that many combinations (of 20 items), it will be impossible to output a list of of all the combinations (it would never fit in memory). This is why the function is written as a generator. Still, it would take a long time (weeks) to go through all the combinations produced by the generator function on a list of 20 items.