Search code examples
pythonlistchunks

Splitting a list into N parts of approximately equal length


What is the best way to divide a list into roughly equal parts? For example, if the list has 7 elements and is split it into 2 parts, we want to get 3 elements in one part, and the other should have 4 elements.

I'm looking for something like even_split(L, n) that breaks L into n parts.

def chunks(L, n):
    """ Yield successive n-sized chunks from L.
    """
    for i in range(0, len(L), n):
        yield L[i:i+n]

The code above gives chunks of 3, rather than 3 chunks. I could simply transpose (iterate over this and take the first element of each column, call that part one, then take the second and put it in part two, etc), but that destroys the ordering of the items.


Solution

  • This code is broken due to rounding errors. Do not use it!!!

    assert len(chunkIt([1,2,3], 10)) == 10  # fails
    

    Here's one that could work:

    def chunkIt(seq, num):
        avg = len(seq) / float(num)
        out = []
        last = 0.0
    
        while last < len(seq):
            out.append(seq[int(last):int(last + avg)])
            last += avg
    
        return out
    

    Testing:

    >>> chunkIt(range(10), 3)
    [[0, 1, 2], [3, 4, 5], [6, 7, 8, 9]]
    >>> chunkIt(range(11), 3)
    [[0, 1, 2], [3, 4, 5, 6], [7, 8, 9, 10]]
    >>> chunkIt(range(12), 3)
    [[0, 1, 2, 3], [4, 5, 6, 7], [8, 9, 10, 11]]