将清单大致等份的最佳方法是什么?例如,如果列表有7个元素,并将其分为2部分,我们希望其中一部分有3个元素,而另一部分应该有4个元素。

我正在寻找类似even_split(L, n)的东西,它将L分解为n部分。

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

上面的代码给出了3个块,而不是3个块。我可以简单地转置(遍历这个,取每列的第一个元素,称之为第一部分,然后取第二个元素,把它放在第二部分,等等),但这破坏了项目的顺序。


当前回答

这段代码为我工作(python3兼容):

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

示例(适用于bytearray类型,但也适用于列表):

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')]

其他回答

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]

例子:

L = [a for a in range(97)]应由10个部分组成,除最后一个部分外,每个部分有9个元素。

输出:

[[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]]
#!/usr/bin/python


first_names = ['Steve', 'Jane', 'Sara', 'Mary','Jack','Bob', 'Bily', 'Boni', 'Chris','Sori', 'Will', 'Won','Li']

def chunks(l, n):
for i in range(0, len(l), n):
    # Create an index range for l of n items:
    yield l[i:i+n]

result = list(chunks(first_names, 5))
print result

从这个链接中选择,这对我很有帮助。我有一个预先定义好的列表。

这将通过一个表达式将其拆分为相等的部分,同时保持顺序:

myList = list(range(18))  # given list
N = 5  # desired number of parts

[myList[(i*len(myList))//N:((i+1)*len(myList))//N] for i in range(N)]
# [[0, 1, 2], [3, 4, 5, 6], [7, 8, 9], [10, 11, 12, 13], [14, 15, 16, 17]]

各部分的差异不超过一个元素。把18分成5份,结果是3 + 4 + 3 + 4 + 4 = 18。

这段代码为我工作(python3兼容):

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

示例(适用于bytearray类型,但也适用于列表):

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')]

如果你把n个元素分成大约k个块,你可以让n % k个块1个元素比其他块大,以分配额外的元素。

下面的代码将给出块的长度:

[(n // k) + (1 if i < (n % k) else 0) for i in range(k)]

示例:n=11, k=3结果为[4,4,3]

然后你可以很容易地计算块的起始索引:

[i * (n // k) + min(i, n % k) for i in range(k)]

示例:n=11, k=3结果为[0,4,8]

使用第i+1块作为边界,我们得到列表l的第i块(len n)是

l[i * (n // k) + min(i, n % k):(i+1) * (n // k) + min(i+1, n % k)]

作为最后一步,使用列表理解从所有块创建一个列表:

[l[i * (n // k) + min(i, n % k):(i+1) * (n // k) + min(i+1, n % k)] for i in range(k)]

示例:n=11, k=3, l=range(n) results in [range(0,4), range(4,8), range(8,11)]