0

Suppose I have an integer n and I need to partition it into k-sized ranges such that the result is a list of tuples like this :

[(0, k - 1), (k, 2*k - 1), ...]

How can I do this elegantly in python ? I am not asking how to partition a list here, I'm asking how to partition an integer, and only get the starting and last indices of the ranges in a list.

Jarvis
  • 8,494
  • 3
  • 27
  • 58

2 Answers2

1

The range() function takes a third step parameter:

>>> for i in range(0,15,3):
>>>     print(i)
...
... 0
3
6
9
12

You can use that as the bottom part of your tuple, and add k or k-1 to get the top part.

list_of_tuples = []
for i in range(0,n,k):
    list_of_tuples.append( tuple(i, i+k-1) )

You can invert this with a comprehension if you like:

lot = [ (i,i+k) for i in range(0,n,k) ]

(Not subtracting one is a good idea if you're going to feed these numbers into a range().)

aghast
  • 14,785
  • 3
  • 24
  • 56
0
>>> def gen_include_n(n, k):
...     a = zip(range(0, n + 1, k), range(k - 1, n + k, k))
...     a[-1] = (a[-1][0], min(n, a[-1][1]))
...     return a
...
>>> gen_include_n(10,1)
[(0, 0), (1, 1), (2, 2), (3, 3), (4, 4), (5, 5), (6, 6), (7, 7), (8, 8), (9, 9), (10, 10)]
>>> gen_include_n(10,2)
[(0, 1), (2, 3), (4, 5), (6, 7), (8, 9), (10, 10)]
>>> gen_include_n(10,6)
[(0, 5), (6, 10)]
>>> gen_include_n(10,10)
[(0, 9), (10, 10)]
>>> gen_include_n(10,11)
[(0, 10)]

>>> def gen_exclude_n(n, k):
...     a = zip(range(0, n, k), range(k - 1, n + k - 1, k))
...     a[-1] = (a[-1][0], min(n - 1, a[-1][1]))
...     return a
...
>>> gen_exclude_n(10,1)
[(0, 0), (1, 1), (2, 2), (3, 3), (4, 4), (5, 5), (6, 6), (7, 7), (8, 8), (9, 9)]
>>> gen_exclude_n(10,2)
[(0, 1), (2, 3), (4, 5), (6, 7), (8, 9)]
>>> gen_exclude_n(10,6)
[(0, 5), (6, 9)]
>>> gen_exclude_n(10,10)
[(0, 9)]
>>> gen_exclude_n(10,11)
[(0, 9)]
lazyplayer
  • 373
  • 1
  • 8