Skip to content Skip to sidebar Skip to footer

Iterating Over Partitions In Python

I was wondering what the best way is (in Python) to iterate over partitions of a list of a given size. Say, for example, we have the list [1,2,3,4,5] and we want k=3 partitions. A

Solution 1:

I would use the same idea as yours without pairwise:

from itertools import combinations

defpartitions(items, k):

    defsplit(indices):
        i=0for j in indices:
            yield items[i:j]
            i = j
        yield items[i:]

    for indices in combinations(range(1, len(items)), k-1):
        yieldlist(split(indices))

Solution 2:

I accomplished what I was trying to do by writing:

from itertools import tee, izip, combinations

defpartitions(items, k):
    N = len(items)

    defpairwise(iterable):  # Taken from itertools recipies
        a, b = tee(iterable)
        next(b, None)
        return izip(a, b)

    defapplyPart(part, items):
        lists = []
        for l,h in pairwise([0] + part + [N]):
            lists.append(items[l:h])
        return lists

    for part in combinations(range(1, N), k - 1):
        yield applyPart(list(part), items)

Solution 3:

This could be somewhat inefficient for larger lists, but it works:

from itertools import product, islice

def partitions(seq, k):
    for c in product(xrange(1, len(seq)+1), repeat=k):
        if sum(c) == len(seq):
            it = iter(seq)
            yield [list(islice(it, x)) for x in c]

for part in partitions([1,2,3,4,5], 3):
    print part

Output:

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

For bigger lists what you need to is find all k sized subsets of range(1, len(sequence)+1) that sum to the length of the sequence and then slice the sequence based on them.

Related: http://www.algorithmist.com/index.php/Coin_Change

Post a Comment for "Iterating Over Partitions In Python"