将清单大致等份的最佳方法是什么?例如,如果列表有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个块。我可以简单地转置(遍历这个,取每列的第一个元素,称之为第一部分,然后取第二个元素,把它放在第二部分,等等),但这破坏了项目的顺序。
如果你把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)]
这将通过一个表达式将其拆分为相等的部分,同时保持顺序:
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。
在这种情况下,我自己编写了代码:
def chunk_ports(port_start, port_end, portions):
if port_end < port_start:
return None
total = port_end - port_start + 1
fractions = int(math.floor(float(total) / portions))
results = []
# No enough to chuck.
if fractions < 1:
return None
# Reverse, so any additional items would be in the first range.
_e = port_end
for i in range(portions, 0, -1):
print "i", i
if i == 1:
_s = port_start
else:
_s = _e - fractions + 1
results.append((_s, _e))
_e = _s - 1
results.reverse()
return results
Divide_ports(1,10,9)将返回
[(1, 2), (3, 3), (4, 4), (5, 5), (6, 6), (7, 7), (8, 8), (9, 9), (10, 10)]
舍入linspace并将其用作索引是一种比amit12690建议的更简单的解决方案。
function chunks=chunkit(array,num)
index = round(linspace(0,size(array,2),num+1));
chunks = cell(1,num);
for x = 1:num
chunks{x} = array(:,index(x)+1:index(x+1));
end
end
def chunkify(target_list, chunk_size):
return [target_list[i:i+chunk_size] for i in range(0, len(target_list), chunk_size)]
>>> l = [5432, 432, 67, "fdas", True, True, False, (4324,131), 876, "ofsa", 8, 909, b'765']
>>> print(chunkify(l, 3))
>>> [[5432, 432, 67], ['fdas', True, True], [False, (4324, 131), 876], ['ofsa', 8, 909], [b'765']]