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
Here is my solution:
def chunks(l, amount):
if amount < 1:
raise ValueError('amount must be positive integer')
chunk_len = len(l) // amount
leap_parts = len(l) % amount
remainder = amount // 2 # make it symmetrical
i = 0
while i < len(l):
remainder += leap_parts
end_index = i + chunk_len
if remainder >= amount:
remainder -= amount
end_index += 1
yield l[i:end_index]
i = end_index
Produces
>>> list(chunks([1, 2, 3, 4, 5, 6, 7], 3))
[[1, 2], [3, 4, 5], [6, 7]]
Here's another variant that spreads the "remaining" elements evenly among all the chunks, one at a time until there are none left. In this implementation, the larger chunks occur at the beginning the process.
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
For example, generate 4 chunks from a list of 14 elements:
>>> 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]
Have a look at numpy.split:
>>> a = numpy.array([1,2,3,4])
>>> numpy.split(a, 2)
[array([1, 2]), array([3, 4])]
Rounding the linspace and using it as an index is an easier solution than what amit12690 proposes.
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
say you want to split into 5 parts:
p1, p2, p3, p4, p5 = np.split(df, 5)
This code is broken due to rounding errors. Do not use it!!!
assert len(chunkIt([1,2,3], 10)) == 10 # fails
Here's one that could work:
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
Testing:
>>> 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]]