协慌网

登录 贡献 社区

如何使用十进制 range()步长值?

有没有办法在 0 和 1 之间以 0.1 步进?

我以为我可以像下面那样做,但是失败了:

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

相反,它说 step 参数不能为零,这是我没有想到的。

答案

与其直接使用小数步,不如用所需的点数来表达这一点要安全得多。否则,浮点舍入错误可能会给您带来错误的结果。

您可以使用NumPy库中的 linspace函数(该库不是标准库的一部分,但相对容易获得)。 linspace需要返回多个点,还可以指定是否包括正确的端点:

>>> 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])

如果您确实要使用浮点步长值,则可以使用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])

但是,浮点舍入错误导致问题。这是一个简单的情况,当四舍五入错误导致arange仅产生 3 个数字时,range 会产生一个长度为 4 的数组:

>>> numpy.arange(1, 1.3, 0.1)
array([1. , 1.1, 1.2, 1.3])

Python 的 range()只能做整数,不能做浮点数。在您的特定情况下,您可以改用列表推导:

[x * 0.1 for x in range(0, 10)]

(用该表达式将调用替换为 range。)

对于更一般的情况,您可能需要编写自定义函数或生成器。

'xrange([start],stop [,step])' 的基础上,您可以定义一个生成器,该生成器接受并生成您选择的任何类型(坚持支持+<类型):

>>> 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']
>>>