Nathaniel Flath
Nathaniel Flath

Reputation: 16015

Generate all possible splits of a list in Python

I have a list in python:

[1,2,3,4]

I want to generate all the possible splits of this list:

[1,2,3,4]
[1] [2,3,4]
[2] [1,3,4]
[3] [1,2,4]
[4] [1,2,3]
[1,2] [3,4]
[1,3] [2,4]
[1,4] [2,3]

What is the best way to do this? I can generate the first side with itertools.combinations(), but what is the easiest way to calculate the remainder, given the list and a subset?

Upvotes: 1

Views: 2318

Answers (4)

pramod
pramod

Reputation: 1493

from itertools import combinations, chain
x = [1, 2, 3, 4]
subsets = [v for a in range(len(x)) for v in combinations(x, a)]
for i in range(len(subsets)/2 + 1):
    print list(chain(subsets[i])), ' ', [e for e in x if e not in subsets[i]]

output:

[]   [1, 2, 3, 4]
[1]   [2, 3, 4]
[2]   [1, 3, 4]
[3]   [1, 2, 4]
[4]   [1, 2, 3]
[1, 2]   [3, 4]
[1, 3]   [2, 4]
[1, 4]   [2, 3]

Upvotes: 3

Mohd
Mohd

Reputation: 5613

You can use list-comprehension to get the remainder:

[x for x in a if x not in b]

assuming a is the original list and b is the subset you got.

EDIT:

If you want to avoid duplicates you can create a list to check before printing and in the same time check for empty remainder (full list):

a = [1, 2, 3, 4]
b = [list(c) for i in xrange(len(a)) for c in itertools.combinations(a, i+1)]
check = []
for elem in b:
    remainder = [x for x in a if x not in elem]
    if remainder not in check and remainder:
        print '{} {}'.format(elem, remainder)
        check.append(elem)

output:

[1] [2, 3, 4]
[2] [1, 3, 4]
[3] [1, 2, 4]
[4] [1, 2, 3]
[1, 2] [3, 4]
[1, 3] [2, 4]
[1, 4] [2, 3]

Upvotes: 1

calico_
calico_

Reputation: 1221

How about this?

>>> import itertools
>>> x = [1,2,3,4]
>>> for i in range(len(x)):
...     for c in [c for c in itertools.combinations(x, i+1)]:
...             print(list(c), [i for i in x if not i in c])
...
[1] [2, 3, 4]
[2] [1, 3, 4]
[3] [1, 2, 4]
[4] [1, 2, 3]
[1, 2] [3, 4]
[1, 3] [2, 4]
[1, 4] [2, 3]
[2, 3] [1, 4]
[2, 4] [1, 3]
[3, 4] [1, 2]
[1, 2, 3] [4]
[1, 2, 4] [3]
[1, 3, 4] [2]
[2, 3, 4] [1]
[1, 2, 3, 4] []

Upvotes: 0

Prune
Prune

Reputation: 77857

Another way is to turn them both into sets and do a simple set difference.

full = [1, 2, 3, 4]
full_set = set(full)
for partition in itertools.combinations(...):
    remainder = list(full_set - set(partition))
    print partition, remainder

Upvotes: 0

Related Questions