将列表分成大致相等长度的N个部分
如何把一个列表分成大致相等的几部分呢?比如说,如果这个列表有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个块。我可以简单地转置(遍历这个列表,取每一列的第一个元素作为第一部分,然后取第二个元素放入第二部分,依此类推),但这样会打乱元素的顺序。
37 个回答
281
这就是numpy.array_split
的存在意义:
>>> import numpy as np
>>> print(*np.array_split(range(10), 3))
[0 1 2 3] [4 5 6] [7 8 9]
>>> print(*np.array_split(range(10), 4))
[0 1 2] [3 4 5] [6 7] [8 9]
>>> print(*np.array_split(range(10), 5))
[0 1] [2 3] [4 5] [6 7] [8 9]
*感谢Zero Piraeus在6号房间的贡献
336
你可以把它写得很简单,像一个列表生成器一样:
def split(a, n):
k, m = divmod(len(a), n)
return (a[i*k+min(i, m):(i+1)*k+min(i+1, m)] for i in range(n))
举个例子:
>>> list(split(range(11), 3))
[[0, 1, 2, 3], [4, 5, 6, 7], [8, 9, 10]]
78
这段代码有问题,因为它会出现四舍五入错误。不要使用它!!!
assert len(chunkIt([1,2,3], 10)) == 10 # fails
这里有一个可能有效的代码:
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
测试:
>>> 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]]