range()函数的浮点步长参数问题

8
我希望生成类似于这样的列表:

可能是重复问题:
Python decimal range() step value

我想生成像这样的列表:

[0, 0.05, 0.1, 0.15 ... ]

range(0, 1, 0.05) 是一个很好的选择,但它不能正常工作,因为:

range() 函数期望整数步长参数,但得到了浮点数参数。

你有什么更优雅的想法吗? ;)


8
请参见:https://dev59.com/oHRB5IYBdhLWcg3w4bKv - Andy Hayden
1
https://dev59.com/oHRB5IYBdhLWcg3w4bKv - Paul Collingwood
5个回答

6
在Python 3中,range返回一个生成器(不可变序列)...所以我认为我们可以定义一个非常简单的函数,如下所示:
def frange(start,stop, step=1.0):
    while start < stop:
        yield start
        start +=step

所以:
for x in frange(0, 1, 0.05):
   print(x)

Python 不需要很难。

如果你想要一个列表,只需调用:

list(frange(0,1,0.05))

或者修改函数直接返回一个列表。

你可以使用一行代码的解决方案来进行乘法或其他操作,但是在不同的起始和结束值时可能会很棘手。如果你经常使用这种范围,请使用函数并重复使用它。即使是在代码中多次重复使用一行代码也是不好的。


这有点迂琐,但是 range() 返回一个列表。xrange() 返回一个生成器。 - ATOMP
不是在Python 3中。range返回一个生成器(不可变序列),而xrange已经不存在了。我会修复打印输出,以使其清楚地表明它是Python 3。 - nmenezes

6
如果您可以使用numpy,最好使用numpy.linspace。试图在浮点数上拟合range逻辑的函数(包括numpy自己的arange)通常会让人感到困惑,因为不确定结束边界是否出现在列表中。linspace通过要求您明确指定起始点、终止点和所需元素数量来优雅地解决了这个问题:
>>> import numpy
>>> numpy.linspace(0.0, 1.0, 21)
array([ 0.  ,  0.05,  0.1 ,  0.15,  0.2 ,  0.25,  0.3 ,  0.35,  0.4 ,
        0.45,  0.5 ,  0.55,  0.6 ,  0.65,  0.7 ,  0.75,  0.8 ,  0.85,
        0.9 ,  0.95,  1.  ])

你无法获胜:linspace 可能会让人困惑有多少项(“为什么是21而不是20?”)。确实,注释总是必要的。 - LSerni
当我在将初始示例失败后的“20”更改为“21”时,我也在想着完全相同的事情。 :) 尽管如此,这种混淆要比区间是否包含终点(以及如何始终到达那里)的混淆不那么微妙且容易出现意外。这总是一个权衡,但至少在这里很明显,您得到了您所要求的 - 结果数组的“len”确实是21。 - user4815162342
你总是得到你所要求的。这就是编程的悲剧 :) - LSerni
您可以指定是否包含最后一个点。请查看 endpoint 参数。 - Dr. Jan-Philip Gehrcke

3
或者试试这个:
[v*0.05 for v in range(0,int(1/0.05))]

你可能会冒着“刮掉”最后一个元素的风险。我认为在列表推导式中进行除法运算更清晰明了。另一方面,你的方法允许选择是否显式地使用四舍五入或截断来进行范围计算,因此在某些情况下可能更好。 - LSerni
或者你可以自己计算数学公式 [v*0.05 for v in range(0,20)],我只是想展示一行代码也是可能的 :) - Ivan Koblik
1
是的,这就是为什么我+1了你的解决方案。但我更喜欢自己做数学运算,并可能在评论中解释。 - LSerni
@IvanKoblik 我正试图做同样的事情,但我不想生成一个列表。您如何适应您所做的工作类型为 for C in range() 的for循环? - John Doe

1
这个怎么样?
temp = range(0,100,5) # 0,5,10,...,95
final_list = map(lambda x: x/100.0,temp) # becomes 0,0.05,0.10,...,0.95

这并不是非常优雅,但我从未费心去编写一个正确的函数。此外,它只适用于步长为有理数的情况。优点是它足够快速,可以即时完成。

请参阅您的原始帖子的评论以获取更通用和更优雅的解决方案。


1

出了什么问题?

[i/100.0 for i in range(0, 100, 5)]

你可以检查需要的位数(这里是两位),然后使用适当的乘数(1 变成 100,0.05 变成 5)。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接