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]