2

How to get list of the range consisting of floats? Why the below code is not working?

lons = list (range(80.0,90.0,0.05))

print (lons)
2964502
  • 4,301
  • 12
  • 35
  • 55

7 Answers7

7

You can utilise a combination of takewhile and count (from 2.7 onwards), if you didn't want to write your own function, eg:

from itertools import takewhile, count
my_range = list(takewhile(lambda L: L < 90, count(80, 0.05)))
Steve P.
  • 14,489
  • 8
  • 42
  • 72
Jon Clements
  • 138,671
  • 33
  • 247
  • 280
  • obviously you'll want to check that min_val <= max_val, otherwise `takewhile` will run infinitely. – IceArdor Dec 03 '13 at 09:30
  • Your function suffers from the same round-off errors as [this one](http://stackoverflow.com/a/477610/119527). Even the docs suggest against using floating-point values in `count`. – Jonathon Reinhart Dec 03 '13 at 09:44
  • @JonathonReinhart indeed... put anything that gives a sensible result when `+`'d.... such as a `decimal.Decimal` - the question was how to get a range of floats - this provides that... whether the result is ultimately desirable is another thing :) – Jon Clements Dec 03 '13 at 09:46
3

You can use a generator function:

from math import ceil
def solve(start, end, step):
    #http://stackoverflow.com/a/10986098/846892
    for i in xrange(int(ceil((end-start)/step))):
        yield start + step*i
print list(solve(80.0, 90.0, 0.5))
#[80.0, 80.5, 81.0, 81.5, 82.0, 82.5, 83.0, 83.5, 84.0, 84.5, 85.0, 85.5, 86.0, 86.5, 87.0, 87.5, 88.0, 88.5, 89.0, 89.5]

Or using NumPy:

>>> import numpy as np
>>> np.arange(80., 90., .5)                                                                 
array([ 80. ,  80.5,  81. ,  81.5,  82. ,  82.5,  83. ,  83.5,  84. ,                            
        84.5,  85. ,  85.5,  86. ,  86.5,  87. ,  87.5,  88. ,  88.5,                            
        89. ,  89.5])   
Ashwini Chaudhary
  • 244,495
  • 58
  • 464
  • 504
2

From the Python docs for range:

The arguments must be plain integers.

Jonathon Reinhart
  • 132,704
  • 33
  • 254
  • 328
2

range just takes intergers. You can form a range and multiply them by floats to get the numbers you require, like this

lons = [80+x*0.05 for x in range(0,200)]

Be aware you might end up with small rounding "errors" for that many numbers.

doctorlove
  • 18,872
  • 2
  • 46
  • 62
1

range only works for integers. See the documentation at http://docs.python.org/2/library/functions.html#range

The functionality you're looking for is:

def floatrange(min_val, max_val, step):
    val=min_val
    while val < max_val:
        yield val
        val += step
IceArdor
  • 1,961
  • 19
  • 20
1

You can create your own range function to manage floats.

def n_range(x, y, jump):
... while x < y:
... yield x
... x += jump
...
lons = list (n_range(80.0,90.0,0.05))

print (lons)

Prashant Gaur
  • 9,540
  • 10
  • 49
  • 71
1

Someone I respect once said:

There's no point in floating point.

So the actual answer to your question is: You're doing it wrong :)

But as that wouldn't exactly count as an answer here on SO, here's a frange function that could work for you. It elevates everything to ints and yields the floats you want.

As you probably can tell by the code, decpl stands for "decimal places" and defines the resolution of the floating point argument. I don't think there's an easy way to reliably derive that from the value passed to the step argument. (Comments are welcome)

def frange(start, stop, step, decpl):
    exp = 10.0 ** decpl
    for i in xrange(int(start * exp), int(stop*exp), int(step*exp)):
        yield i / exp

print list(frange(80, 90, 0.1, 1))
Burak Arslan
  • 7,671
  • 2
  • 15
  • 24