Welcome, guest | Sign In | My Account | Store | Cart

While using the built-in range function a while ago. I found an odd (perhaps bug) where the range function couldn't use float steps. I am not sure if that was intended for simplicity or not, but I wrote my own range function that goes beyond that anyway.

Python, 10 lines
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
from decimal import Decimal

# replaces default range function to allow more functionality
def range(start, stop=None, step=1):
	if stop==None: stop = start; start = 0
	x = []
	while start < stop:
		x.append(Decimal(str(start)))
		start += Decimal(str(step))
	return x

4 comments

Chris Jones 13 years, 11 months ago  # | flag

I suspect it is this way because of floating point inaccuracy. Personally I would find a way to do what I want using whole integers, or the Decimal module. Relying on FP when you expect accuracy is a common pitfall.

Sunjay Varma (author) 13 years, 11 months ago  # | flag

Thanks for the comment! I updated the function so that it uses the decimal module.

Steven D'Aprano 13 years, 10 months ago  # | flag

It is definitely by design that range() and xrange() don't accept floats. You have to watch out for round-off error. Dealing with open and closed intervals is more complicated.

You might like to look at this recipe here:

http://code.activestate.com/recipes/577068/

which doesn't (yet) support decimal or fractions, but does handle floats.

Your recipe doesn't support counting downwards, like range(10, 0, -0.1). It is also much more expensive to run than the built-in range() function, hence significantly slower, due to repeated conversions to and from strings. And since most calling code will expect integers, not Decimals, it will break other code:

L = ["a", "b", "c"]
for i in range(0, 3, 2):
    # expects 0, 2 but gets Decimal("0"), Decimal("1")
    print L[i]

=> raises TypeError: list indices must be integers

Sunjay Varma (author) 13 years, 9 months ago  # | flag

Interesting. In reality though, for the purpose I used it in at least, I wasn't looking for a very advanced function at all...I was looking for a simple way to just get some floats. :)

Thanks for your comment. I really see what you mean now. :)

Created by Sunjay Varma on Sat, 5 Jun 2010 (MIT)
Python recipes (4591)
Sunjay Varma's recipes (12)

Required Modules

  • (none specified)

Other Information and Tasks