将清单大致等份的最佳方法是什么?例如,如果列表有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个块。我可以简单地转置(遍历这个,取每列的第一个元素,称之为第一部分,然后取第二个元素,把它放在第二部分,等等),但这破坏了项目的顺序。
这将通过一个表达式将其拆分为相等的部分,同时保持顺序:
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。
如果你把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)]
假设你想把一个列表[1、2、3、4、5、6、7、8]分成3个元素列表
如[[1,2,3],[4,5,6],[7,8]],如果剩下的最后一个元素小于3,则将它们分组在一起。
my_list = [1, 2, 3, 4, 5, 6, 7, 8]
my_list2 = [my_list[i:i+3] for i in range(0, len(my_list), 3)]
print(my_list2)
输出:[[1,2,3],[4,5,6],[7,8]]
其中一部分的长度为3。用你自己的块大小替换3。
这是另一种变体,它将“剩余”元素均匀地分布在所有块中,一次一个,直到一个都不剩。在这个实现中,较大的块出现在流程的开头。
def chunks(l, k):
""" Yield k successive chunks from l."""
if k < 1:
yield []
raise StopIteration
n = len(l)
avg = n/k
remainders = n % k
start, end = 0, avg
while start < n:
if remainders > 0:
end = end + 1
remainders = remainders - 1
yield l[start:end]
start, end = end, end+avg
例如,从14个元素的列表中生成4个块:
>>> list(chunks(range(14), 4))
[[0, 1, 2, 3], [4, 5, 6, 7], [8, 9, 10], [11, 12, 13]]
>>> map(len, list(chunks(range(14), 4)))
[4, 4, 3, 3]
你还可以用:
split=lambda x,n: x if not x else [x[:n]]+[split([] if not -(len(x)-n) else x[-(len(x)-n):],n)][0]
split([1,2,3,4,5,6,7,8,9],2)
[[1, 2], [3, 4], [5, 6], [7, 8], [9]]
使用numpy实现。linspace方法。
只需指定要将数组分成的部分的数量。各部门的规模将几乎相同。
例子:
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
给:
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])]