[Tutor] range() fractional increment
Lie Ryan
lie.1296 at gmail.com
Tue Mar 31 07:27:58 CEST 2009
John Fouhy wrote:
> 2009/3/31 james carnell <jimcarnell at yahoo.com>:
>> for row in range(25,31,1):
>> for col in range(10,12, 0.3): #<- Crash Bang doesn't work 0.3 = zero =
>> infinite loop?
>> [...]
>> is there no way to do it with a range function (and have it still look like
>> you're not on crack)?
>
> Well, you could do this:
>
>>>> [float(x)/3 for x in range(30, 37)]
> [10.0, 10.333333333333334, 10.666666666666666, 11.0,
> 11.333333333333334, 11.666666666666666, 12.0]
>
> Or even:
>
>>>> [math.floor(10*float(x)/3)/10 for x in range(30, 37)]
> [10.0, 10.300000000000001, 10.6, 11.0, 11.300000000000001, 11.6, 12.0]
>
> However, the builtin range() only works with integers. I think there
> is a range() function in the python cookbook that will do fractional
> step sizes.
>
> But really, there's nothing wrong with your while loop.
>
You could boil your own range function (beware: binary floating point
may be imprecise)
def frange(start, stop, step):
width = stop - start
n = round(width / step)
return [start + step*i for i in xrange(n)]
or returning generator instead (may be preferable if the size of the
list is extremely large):
def frange(start, stop, step):
width = stop - start
n = round(width / step)
return (start + step*i for i in xrange(n))
slightly obscured version:
def frange(start, stop, step):
return (start + step*i for i in range(round((stop - start) / step)))
more complex homebrew frange may return a class that really emulates
xrange, by implementing __getitem__, iterator protocol, generator
protocol, and all the sugar without ever creating a real list.
More information about the Tutor
mailing list