How to use a decimal range() step value?

前端 未结 30 2171
醉话见心
醉话见心 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:24

    My versions use the original range function to create multiplicative indices for the shift. This allows same syntax to the original range function. I have made two versions, one using float, and one using Decimal, because I found that in some cases I wanted to avoid the roundoff drift introduced by the floating point arithmetic.

    It is consistent with empty set results as in range/xrange.

    Passing only a single numeric value to either function will return the standard range output to the integer ceiling value of the input parameter (so if you gave it 5.5, it would return range(6).)

    Edit: the code below is now available as package on pypi: Franges

    ## frange.py
    from math import ceil
    # find best range function available to version (2.7.x / 3.x.x)
    try:
        _xrange = xrange
    except NameError:
        _xrange = range
    
    def frange(start, stop = None, step = 1):
        """frange generates a set of floating point values over the 
        range [start, stop) with step size step
    
        frange([start,] stop [, step ])"""
    
        if stop is None:
            for x in _xrange(int(ceil(start))):
                yield x
        else:
            # create a generator expression for the index values
            indices = (i for i in _xrange(0, int((stop-start)/step)))  
            # yield results
            for i in indices:
                yield start + step*i
    
    ## drange.py
    import decimal
    from math import ceil
    # find best range function available to version (2.7.x / 3.x.x)
    try:
        _xrange = xrange
    except NameError:
        _xrange = range
    
    def drange(start, stop = None, step = 1, precision = None):
        """drange generates a set of Decimal values over the
        range [start, stop) with step size step
    
        drange([start,] stop, [step [,precision]])"""
    
        if stop is None:
            for x in _xrange(int(ceil(start))):
                yield x
        else:
            # find precision
            if precision is not None:
                decimal.getcontext().prec = precision
            # convert values to decimals
            start = decimal.Decimal(start)
            stop = decimal.Decimal(stop)
            step = decimal.Decimal(step)
            # create a generator expression for the index values
            indices = (
                i for i in _xrange(
                    0, 
                    ((stop-start)/step).to_integral_value()
                )
            )  
            # yield results
            for i in indices:
                yield float(start + step*i)
    
    ## testranges.py
    import frange
    import drange
    list(frange.frange(0, 2, 0.5)) # [0.0, 0.5, 1.0, 1.5]
    list(drange.drange(0, 2, 0.5, precision = 6)) # [0.0, 0.5, 1.0, 1.5]
    list(frange.frange(3)) # [0, 1, 2]
    list(frange.frange(3.5)) # [0, 1, 2, 3]
    list(frange.frange(0,10, -1)) # []
    

提交回复
热议问题