I have the total number of elements in the range N
and a number of chunks nb
I want to divide N
into nb
best possible equal ranges, with just the start number and the end number. So for example, N=24
and nb=5
should output:
0,5 5,10 10,15 15,20 20,24
While N=28
and nb=5
should output:
0,5 5,10 10,16 16,22 22,28 (the rest of `N/nb` division is equally distributed on the 3 last subranges)
Based on one comment, I have this method:
def partition(lst, n):
division = len(lst) / n
return [lst[round(division * i):round(division * (i + 1))] for i in range(n)]
def ranges(N, nb):
return ["{},{}".format(r.start, r.stop) for r in partition(range(N), nb)]
>>> ranges(28, 5)
['0,6', '6,11', '11,17', '17,22', '22,28']
Is there a better way to do this?
It is surely simpler to calculate the start and stop numbers directly rather than slicing a range
object to get them:
def ranges(N, nb):
step = N / nb
return ["{},{}".format(round(step*i), round(step*(i+1))) for i in range(nb)]
This is not as much more efficient than your code that it might look because slicing a range
object takes only O(1)
time, so your existing code is already asymptotically optimal. My version likely improves performance by some constant factor, but it may be small. I do think my version is also a lot clearer though, which may be more important than whatever performance change there might be.