Iterating over partitions in Python

前端 未结 3 738
北恋
北恋 2020-12-19 09:33

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] an

相关标签:
3条回答
  • 2020-12-19 10:09

    I accomplished what I was trying to do by writing:

    from itertools import tee, izip, combinations
    
    def partitions(items, k):
        N = len(items)
    
        def pairwise(iterable):  # Taken from itertools recipies
            a, b = tee(iterable)
            next(b, None)
            return izip(a, b)
    
        def applyPart(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)
    
    0 讨论(0)
  • 2020-12-19 10:10

    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

    0 讨论(0)
  • I would use the same idea as yours without pairwise:

    from itertools import combinations
    
    def partitions(items, k):
    
        def split(indices):
            i=0
            for j in indices:
                yield items[i:j]
                i = j
            yield items[i:]
    
        for indices in combinations(range(1, len(items)), k-1):
            yield list(split(indices))
    
    0 讨论(0)
提交回复
热议问题