How to use a decimal range() step value?

前端 未结 30 2176
醉话见心
醉话见心 2020-11-21 22:34

Is there a way to step between 0 and 1 by 0.1?

I thought I could do it like the following, but it failed:

for i in range(0, 1, 0.1):
    print i


        
相关标签:
30条回答
  • 2020-11-21 23:09

    Building on 'xrange([start], stop[, step])', you can define a generator that accepts and produces any type you choose (stick to types supporting + and <):

    >>> def drange(start, stop, step):
    ...     r = start
    ...     while r < stop:
    ...         yield r
    ...         r += step
    ...         
    >>> i0=drange(0.0, 1.0, 0.1)
    >>> ["%g" % x for x in i0]
    ['0', '0.1', '0.2', '0.3', '0.4', '0.5', '0.6', '0.7', '0.8', '0.9', '1']
    >>> 
    
    0 讨论(0)
  • 2020-11-21 23:09

    I know I'm late to the party here, but here's a trivial generator solution that's working in 3.6:

    def floatRange(*args):
        start, step = 0, 1
        if len(args) == 1:
            stop = args[0]
        elif len(args) == 2:
            start, stop = args[0], args[1]
        elif len(args) == 3:
            start, stop, step = args[0], args[1], args[2]
        else:
            raise TypeError("floatRange accepts 1, 2, or 3 arguments. ({0} given)".format(len(args)))
        for num in start, step, stop:
            if not isinstance(num, (int, float)):
                raise TypeError("floatRange only accepts float and integer arguments. ({0} : {1} given)".format(type(num), str(num)))
        for x in range(int((stop-start)/step)):
            yield start + (x * step)
        return
    

    then you can call it just like the original range()... there's no error handling, but let me know if there is an error that can be reasonably caught, and I'll update. or you can update it. this is StackOverflow.

    0 讨论(0)
  • 2020-11-21 23:09

    I am only a beginner, but I had the same problem, when simulating some calculations. Here is how I attempted to work this out, which seems to be working with decimal steps.

    I am also quite lazy and so I found it hard to write my own range function.

    Basically what I did is changed my xrange(0.0, 1.0, 0.01) to xrange(0, 100, 1) and used the division by 100.0 inside the loop. I was also concerned, if there will be rounding mistakes. So I decided to test, whether there are any. Now I heard, that if for example 0.01 from a calculation isn't exactly the float 0.01 comparing them should return False (if I am wrong, please let me know).

    So I decided to test if my solution will work for my range by running a short test:

    for d100 in xrange(0, 100, 1):
        d = d100 / 100.0
        fl = float("0.00"[:4 - len(str(d100))] + str(d100))
        print d, "=", fl , d == fl
    

    And it printed True for each.

    Now, if I'm getting it totally wrong, please let me know.

    0 讨论(0)
  • 2020-11-21 23:10

    Rather than using a decimal step directly, it's much safer to express this in terms of how many points you want. Otherwise, floating-point rounding error is likely to give you a wrong result.

    You can use the linspace function from the NumPy library (which isn't part of the standard library but is relatively easy to obtain). linspace takes a number of points to return, and also lets you specify whether or not to include the right endpoint:

    >>> np.linspace(0,1,11)
    array([ 0. ,  0.1,  0.2,  0.3,  0.4,  0.5,  0.6,  0.7,  0.8,  0.9,  1. ])
    >>> np.linspace(0,1,10,endpoint=False)
    array([ 0. ,  0.1,  0.2,  0.3,  0.4,  0.5,  0.6,  0.7,  0.8,  0.9])
    

    If you really want to use a floating-point step value, you can, with numpy.arange.

    >>> import numpy as np
    >>> np.arange(0.0, 1.0, 0.1)
    array([ 0. ,  0.1,  0.2,  0.3,  0.4,  0.5,  0.6,  0.7,  0.8,  0.9])
    

    Floating-point rounding error will cause problems, though. Here's a simple case where rounding error causes arange to produce a length-4 array when it should only produce 3 numbers:

    >>> numpy.arange(1, 1.3, 0.1)
    array([1. , 1.1, 1.2, 1.3])
    
    0 讨论(0)
  • 2020-11-21 23:10

    Increase the magnitude of i for the loop and then reduce it when you need it.

    for i * 100 in range(0, 100, 10):
        print i / 100.0
    

    EDIT: I honestly cannot remember why I thought that would work syntactically

    for i in range(0, 11, 1):
        print i / 10.0
    

    That should have the desired output.

    0 讨论(0)
  • 2020-11-21 23:10

    For completeness of boutique, a functional solution:

    def frange(a,b,s):
      return [] if s > 0 and a > b or s < 0 and a < b or s==0 else [a]+frange(a+s,b,s)
    
    0 讨论(0)
提交回复
热议问题