Splitting a list into N parts of approximately equal length

前端 未结 30 1339
迷失自我
迷失自我 2020-11-22 16:16

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 o

相关标签:
30条回答
  • 2020-11-22 17:03

    This one provides chunks of length <= n, >= 0

    def

     chunkify(lst, n):
        num_chunks = int(math.ceil(len(lst) / float(n))) if n < len(lst) else 1
        return [lst[n*i:n*(i+1)] for i in range(num_chunks)]
    

    for example

    >>> chunkify(range(11), 3)
    [[0, 1, 2], [3, 4, 5], [6, 7, 8], [9, 10]]
    >>> chunkify(range(11), 8)
    [[0, 1, 2, 3, 4, 5, 6, 7], [8, 9, 10]]
    
    0 讨论(0)
  • 2020-11-22 17:04

    this code works for me (Python3-compatible):

    def chunkify(tab, num):
        return [tab[i*num: i*num+num] for i in range(len(tab)//num+(1 if len(tab)%num else 0))]
    

    example (for bytearray type, but it works for lists as well):

    b = bytearray(b'\x01\x02\x03\x04\x05\x06\x07\x08')
    >>> chunkify(b,3)
    [bytearray(b'\x01\x02\x03'), bytearray(b'\x04\x05\x06'), bytearray(b'\x07\x08')]
    >>> chunkify(b,4)
    [bytearray(b'\x01\x02\x03\x04'), bytearray(b'\x05\x06\x07\x08')]
    
    0 讨论(0)
  • 2020-11-22 17:05

    Implementation using numpy.linspace method.

    Just specify the number of parts you want the array to be divided in to.The divisions will be of nearly equal size.

    Example :

    import numpy as np   
    a=np.arange(10)
    print "Input array:",a 
    parts=3
    i=np.linspace(np.min(a),np.max(a)+1,parts+1)
    i=np.array(i,dtype='uint16') # Indices should be floats
    split_arr=[]
    for ind in range(i.size-1):
        split_arr.append(a[i[ind]:i[ind+1]]
    print "Array split in to %d parts : "%(parts),split_arr
    

    Gives :

    Input array: [0 1 2 3 4 5 6 7 8 9]
    Array split in to 3 parts :  [array([0, 1, 2]), array([3, 4, 5]), array([6, 7, 8, 9])]
    
    0 讨论(0)
  • 2020-11-22 17:05
    def evenly(l, n):
        len_ = len(l)
        split_size = len_ // n
        split_size = n if not split_size else split_size
        offsets = [i for i in range(0, len_, split_size)]
        return [l[offset:offset + split_size] for offset in offsets]
    

    Example:

    l = [a for a in range(97)] should be consist of 10 parts, each have 9 elements except the last one.

    Output:

    [[0, 1, 2, 3, 4, 5, 6, 7, 8],
     [9, 10, 11, 12, 13, 14, 15, 16, 17],
     [18, 19, 20, 21, 22, 23, 24, 25, 26],
     [27, 28, 29, 30, 31, 32, 33, 34, 35],
     [36, 37, 38, 39, 40, 41, 42, 43, 44],
     [45, 46, 47, 48, 49, 50, 51, 52, 53],
     [54, 55, 56, 57, 58, 59, 60, 61, 62],
     [63, 64, 65, 66, 67, 68, 69, 70, 71],
     [72, 73, 74, 75, 76, 77, 78, 79, 80],
     [81, 82, 83, 84, 85, 86, 87, 88, 89],
     [90, 91, 92, 93, 94, 95, 96]]
    
    0 讨论(0)
  • 2020-11-22 17:06

    Changing the code to yield n chunks rather than chunks of n:

    def chunks(l, n):
        """ Yield n successive chunks from l.
        """
        newn = int(len(l) / n)
        for i in xrange(0, n-1):
            yield l[i*newn:i*newn+newn]
        yield l[n*newn-newn:]
    
    l = range(56)
    three_chunks = chunks (l, 3)
    print three_chunks.next()
    print three_chunks.next()
    print three_chunks.next()
    

    which gives:

    [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17]
    [18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35]
    [36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55]
    

    This will assign the extra elements to the final group which is not perfect but well within your specification of "roughly N equal parts" :-) By that, I mean 56 elements would be better as (19,19,18) whereas this gives (18,18,20).

    You can get the more balanced output with the following code:

    #!/usr/bin/python
    def chunks(l, n):
        """ Yield n successive chunks from l.
        """
        newn = int(1.0 * len(l) / n + 0.5)
        for i in xrange(0, n-1):
            yield l[i*newn:i*newn+newn]
        yield l[n*newn-newn:]
    
    l = range(56)
    three_chunks = chunks (l, 3)
    print three_chunks.next()
    print three_chunks.next()
    print three_chunks.next()
    

    which outputs:

    [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18]
    [19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37]
    [38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55]
    
    0 讨论(0)
  • 2020-11-22 17:06

    1>

    import numpy as np
    
    data # your array
    
    total_length = len(data)
    separate = 10
    sub_array_size = total_length // separate
    safe_separate = sub_array_size * separate
    
    splited_lists = np.split(np.array(data[:safe_separate]), separate)
    splited_lists[separate - 1] = np.concatenate(splited_lists[separate - 1], 
    np.array(data[safe_separate:total_length]))
    
    splited_lists # your output
    

    2>

    splited_lists = np.array_split(np.array(data), separate)
    
    0 讨论(0)
提交回复
热议问题