Python 浮动式步进范围

Python 浮动式步进范围,python,range,Python,Range,基本上说,范围必须与此实现完全相同(对于肯定的步骤): 它还说它的参数必须是整数。为什么呢?如果步骤是浮动的,那么这个定义不是也完全有效吗 在我的例子中,我特别需要一个range函数,它接受浮点类型作为其step参数。Python中是否有任何工具,或者我是否需要实现自己的工具 更具体地说:我如何以一种好的方式将此C代码直接转换为Python(即,不只是通过而手动执行-循环): for(float x=0;x>列表(kahan_范围(0,1,0.0001))[-1] 0.9999 >>>列表(k

基本上说,
范围
必须与此实现完全相同(对于肯定的
步骤
):

它还说它的参数必须是整数。为什么呢?如果步骤是浮动的,那么这个定义不是也完全有效吗

在我的例子中,我特别需要一个
range
函数,它接受浮点类型作为其
step
参数。Python中是否有任何工具,或者我是否需要实现自己的工具


更具体地说:我如何以一种好的方式将此C代码直接转换为Python(即,不只是通过
而手动执行
-循环):

for(float x=0;x<10;x+=0.5f){/*…*/}

可能是因为您不能拥有iterable的一部分。另外,
浮点数
是不精确的。

当您将浮点数相加时,通常会有一点错误。
范围(0.0,2.2,1.1)
会返回
[0.0,1.1]
还是
[0.0,1.1,2.1999999]
?没有严格的分析是无法确定的


如果你真的需要的话,你发布的代码是可以解决的。请注意可能存在的缺点。

一种解释可能是浮点舍入问题。例如,如果你可以打电话

range(0, 0.4, 0.1)
您可能期望输出为

[0, 0.1, 0.2, 0.3]
但事实上你得到的是

[0, 0.1, 0.2000000001, 0.3000000001]
由于四舍五入问题。由于range通常用于生成某种类型的索引,所以它只是整数

不过,如果你想要一个浮动范围生成器,你可以自己滚动

def xfrange(start, stop, step):
    i = 0
    while start + i * step < stop:
        yield start + i * step
        i += 1
def xfrange(启动、停止、步骤):
i=0
启动+i*步骤<停止时:
产量开始+i*步
i+=1
您可以使用


编辑:文档首选。感谢@Droogans注意到=)

浮点运算的问题是,由于不准确,您可能无法获得与预期相同的项数。如果你在玩多项式,而多项式的精确项数是非常重要的,那么这可能是一个真正的问题

你真正想要的是一个算术级数;下面的代码对于
int
float
complex
,将非常有效。。。还有字符串和列表

def arithmetic_progression(start, step, length):
    for i in xrange(length):
        yield start + i * step
请注意,与任何保持运行总数的替代方案相比,此代码更有可能使您的最后一个值处于预期值的牛市范围内

>>> 10000 * 0.0001, sum(0.0001 for i in xrange(10000))
(1.0, 0.9999999999999062)
>>> 10000 * (1/3.), sum(1/3. for i in xrange(10000))
(3333.333333333333, 3333.3333333337314)
更正:这里有一个:

def kahan_范围(启动、停止、步骤): 断言步骤>0.0 总计=开始 compo=0.0 而总<停止: 总产量 y=阶跃-复合 温度=总温度+y 成分=(温度-总计)-y 总计=温度 >>>列表(kahan_范围(0,1,0.0001))[-1] 0.9999 >>>列表(kahan_范围(0,3333.3334,1/3.)[-1] 3333.333333333333 >>>
为了能够在范围表达式中使用十进制数,下面是一种很酷的方法:
[x*0.1表示范围(0,10)内的x)]

这里有一个可能足够好的特例:

 [ (1.0/divStep)*x for x in range(start*divStep, stop*divStep)]
在您的情况下,这将是:

#for(float x = 0; x < 10; x += 0.5f) { /* ... */ } ==>
start = 0
stop  = 10
divstep = 1/.5 = 2 #This needs to be int, thats why I said 'special case'

这就是我要使用的:

numbers = [float(x)/10 for x in range(10)]
而不是:

numbers = [x*0.1 for x in range(10)]
that would return :
[0.0, 0.1, 0.2, 0.30000000000000004, 0.4, 0.5, 0.6000000000000001, 0.7000000000000001, 0.8, 0.9]

希望有帮助。

你不能在循环中使用
返回
产生
关键字,使用
中断
。看起来你可以!我认为那是不可能的。。我确信当我尝试类似的方法时出现了错误以你发布的代码为例,将其重命名为
float\u range
-done.@Tim:
return
变成
raise StopIteration
return
获取
SyntaxError:“return”和生成器中的参数
——即使对于
return None
。实际上,
range()
返回一个列表。OP描述的实际上是
xrange()
,它一次返回一个元素。当然可以(它的行为方式很自然)。浮动货币总是如此。所以当然,如果
range
支持浮动,那么它的行为是完全合法的。所以我真的不明白为什么不应该。@Albert:通常没有什么理由怀疑为什么会做出这样的决定;他们就是这样。在这种情况下,有限的用例将被imho中潜在的讨厌的bug所超越。你正在积累舍入误差。请改用这个:`i=0;r=启动,r<停止:i+=1;r=开始+i*步;很明显,我错过了Cees的评论。当然,你是绝对正确的,我的版本会疯狂地累积舍入误差。我有点不安重温它,事实上,因为它是如此明显的错误的事情做!但现在终于修好了。谢谢你提醒我。它因负
步骤而中断,请修复
while
条件,如:
while(start+i*step)*(-1如果步骤<0,否则1)
第一段说明:当使用非整数步骤(如0.1)时,结果通常不一致。最好用于这些情况。请注意,
linspace
具有不同的接口,甚至没有numpy.arange。我做了一个xfrange函数,没有浮点精度问题。看看吧;)这并不能回答这个问题。若要评论或要求作者澄清,请在其帖子下方留下评论-您可以随时在自己的帖子上发表评论,一旦您有足够的评论,您就可以发表评论。@RaisAlam请注意,如果他使用0.5而不是0.1,则不会出现意外行为。如果您的“范围”有很多数字和“步骤”如果0.1的值更小,例如.00000001,那么这将不起作用,脚本将在大多数计算机上挂起。我们需要一些能模拟xrange功能的东西。我们需要一个iterable/generator,而不是列表理解。在这种情况下,上面的fxrange效果更好。非常简单的列表理解解决方案,谢谢@ekta使用
()
而不是
[]
将其转换为生成器。我只需要一些我期望从本机
范围
中得到的简单东西——我对这个解决方案很满意
#for(float x = 0; x < 10; x += 0.5f) { /* ... */ } ==>
start = 0
stop  = 10
divstep = 1/.5 = 2 #This needs to be int, thats why I said 'special case'
>>> [ .5*x for x in range(0*2, 10*2)]
[0.0, 0.5, 1.0, 1.5, 2.0, 2.5, 3.0, 3.5, 4.0, 4.5, 5.0, 5.5, 6.0, 6.5, 7.0, 7.5, 8.0, 8.5, 9.0, 9.5]
numbers = [float(x)/10 for x in range(10)]
numbers = [x*0.1 for x in range(10)]
that would return :
[0.0, 0.1, 0.2, 0.30000000000000004, 0.4, 0.5, 0.6000000000000001, 0.7000000000000001, 0.8, 0.9]