wong2
wong2

Reputation: 35740

Python split iterables into combinations

given a iterable 'ABCD', I'd like to get all (1,3) pairs, eg:

('A', 'BCD'),
('B', 'ACD'),
('C', 'ABD'),
('D', 'ABC')

I've found itertools.combination, however, it can only give ['BCD', 'ACD', 'ABD', 'ABC'], not including the 1 part.

it there an easy way to do this in python?

Upvotes: 0

Views: 103

Answers (2)

lemonhead
lemonhead

Reputation: 5518

How about:

x = 'ABCD'
[(x[i], x[:i] + x[i+1:]) for i in range(len(x))]
# Outputs:
# [('A', 'BCD'), ('B', 'ACD'), ('C', 'ABD'), ('D', 'ABC')]

Upvotes: 3

Raymond Hettinger
Raymond Hettinger

Reputation: 226376

The easiest way is to use set differences to identify to the part excluded by the generated combination:

>>> from itertools import combinations
>>> population = set('ABCD')
>>> for group in combinations(population, 3):
        remainder = population.difference(group)
        result = ''.join(remainder), ''.join(group)
        print(result)

('D', 'ACB')
('B', 'ACD')
('C', 'ABD')
('A', 'CBD')

This technique works for partitions other than just (1, 3). For example, here are the (2, 3) partitions:

>>> population = set('ABCDE')
>>> for group in combinations(population, 3):
    remainder = population.difference(group)
    result = ''.join(remainder), ''.join(group)
    print(result)


('ED', 'ACB')
('BD', 'ACE')
('BE', 'ACD')
('CD', 'ABE')
('CE', 'ABD')
('CB', 'AED')
('AD', 'CBE')
('AE', 'CBD')
('AB', 'CED')
('AC', 'BED')

Upvotes: 4

Related Questions