Inclusive range() in Python
March 6th, 2008
The Python’s built-in range() is an extremely useful function, but has a little problem: it doesn’t include the right extreme of the range. For example, a call to range(1, 10) will be evaluated to this a list of numbers from 1 to 9 (not including 10):
>>> range(1, 10)
[1, 2, 3, 4, 5, 6, 7, 8, 9]
Today I need for a work a range() function that includes the right extreme, so I had to develop mine. Here it is:
def inclusive_range(start, stop, step=1):
"""
A range() clone, but this includes the extremes
"""
l = []
x = start
while x <= stop:
l.append(x)
x += step
return l
Of course there are faster implementations of this function around here (and if you know one, please let me know) and surely this one is not one of the fastest, but it works and that solves my problem right now.
How fast is:
def inclusive_range(start, stop, step=1):
return(range(start, stop+1, step))
?
Comment by Xubuntix — March 7th, 2008 at 0:10
goddamn… this is what happens when coding 8 hours straight on…
Comment by Giuliani Vito, Ivan — March 7th, 2008 at 0:41
You may want to consider a situation with a negative step as well, in which case it is just better to add the step (positive or negative) to the stop:
def inclusive_range(start, stop, step=1):
return(range(start, stop+step, step))
-Chris
Comment by Chris Brinker — April 22nd, 2008 at 22:20
Dern lack of preview :)
def inclusive_range(start, stop, step=1):
return(range(start, stop+step, step))
Comment by Chris Brinker — April 22nd, 2008 at 22:21
irange = lambda x,y,z=1: range(x,y+1,z)
Comment by Wes Turner — June 5th, 2008 at 6:54
@ Comments 1 & 2:
Lol. That’s great — been there.
Comment by Kenny Katzgrau — August 16th, 2008 at 16:17
I think Chris’s definition is not quite right. Consider these calls:
range(1, 5, 3) => [1, 4]
inclusive_range(1, 5, 3) => [1, 4, 7]
The inclusive range shouldn’t include 7, since it is strictly greater than 5.
I think this is one way to define the interface with the same semantics as the range() built-in other than changing the right bound to be inclusive:
def inclusive_range(*args):
if len(args) == 1:
start = 0
stop = args[0]
step = 1
elif len(args) == 2:
(start, stop) = args
step = 1
elif len(args) == 3:
(start, stop, step) = args
else:
raise TypeError("Expected 1-3 args, got", len(args))
if step > 0:
return range(start, stop + 1, step)
else:
return range(start, stop - 1, step)
Comment by Jon — June 19th, 2009 at 21:16
def inclusive_range(*args):
numargs = len(args)
if numargs < 1:
raise TypeError("irange requires at least one argument.")
elif numargs == 1:
stop = args[0];
start = 0;
step = 1;
elif numargs == 2:
(start,stop) = args
step = 1
elif numargs == 3:
(start,stop,step) = args
else:
raise TypeError("irange expected at most 3 arguments, got %s" % (str(numargs)))
i = start
if step == 0:
step = 1
while i <= stop:
yield i
i += step
Comment by Nick — June 8th, 2011 at 12:12
def inclusive_range(start, stop=None, step=1):
if stop == None:
start, stop = 0, start
extension = -1 if step < 0 else 1
return range(start, stop + extension, step)
It’ll differ from range() in that a second argument of None will cause it to do a [0..N] range as in one argument. It’ll also throw somewhat different errors if you feed it strings or similar, but so do most of the other examples.
The other code probably communicates better, but this was fun to try to write concisely!
Comment by Geo — June 30th, 2011 at 11:29
Nick’s solution will best serve the purpose and behaves exactly like range() of Python. That is, it can be passed 1, 2 or 3 arguments just like the range(). Anything else would raise an appropriate exception.
Example:
inclusive_range(25) for range from 0 to 25 inclusive with default step of 1.
inclusive_range(10,25) for range from 10 to 25 inclusive with default step of 1.
inclusive_range(10,25,5) for range from 10 to 25 inclusive with a custom step of 5.
inclusive_range and inclusive_range(1,10,1,32) will raise exceptions.
Comment by Abhinav Sood — August 2nd, 2011 at 13:54
I’d suggest that you create an iterator like this:
class inclusive_range():
def __init__(self, *args):
numargs = len(args)
if numargs < 1:
raise TypeError('Inclusive Range requires at least 1 argument')
elif numargs == 1:
self.stop = args[0]
self.start, self.step = 0, 1
elif numargs == 2:
(self.start, self.stop) = args
self.step = 1
elif numargs == 3:
(self.start, self.stop, self.step) = args
else:
raise TypeError('Inclusive Range expects at the most 3 arguments, got {}'.format(numargs))
def __iter__(self):
i = self.start
while i <= self.stop:
yield i
i += self.step
Then you can use it like an iterable object like range(). For example,
for i in inclusive_range(5,100,5): print(i, end = ' ')
Comment by Abhinav Sood — August 4th, 2011 at 21:43