范围与浮动types的步骤

文档基本上说, range必须像这个实现一样行事(对于积极的step ):

 def range(start, stop, step): x = start while True: if x >= stop: return yield x x += step 

它也说它的论据必须是整数。 这是为什么? 如果step是一个float,那么这个定义是不是完全有效?

就我而言,我是特别的。 需要一个接受floattypes作为其step参数的range函数。 有没有在Python中,或者我需要实现我自己的?


更具体一点:我如何将这个C代码直接转换成Python的方式(即不是通过手动的while -loop来完成):

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

你可以使用numpy.arange

编辑:文档更喜欢numpy.linspace感谢@Droogans for noticing =)

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

 range(0, 0.4, 0.1) 

你可能会期望输出

 [0, 0.1, 0.2, 0.3] 

但你实际上得到了类似的东西

 [0, 0.1, 0.2000000001, 0.3000000001] 

由于四舍五入的问题。 由于范围通常用于生成某种索引,因此它只是整数。

不过,如果你想要一个浮动范围发生器,你可以推出自己的。

 def xfrange(start, stop, step): i = 0 while start + i * step < stop: yield start + i * step i += 1 

为了能够在范围expression式中使用十进制数,一个很酷的方法是:[x * 0.1(范围内的x)(0,10)]

浮点的问题在于,由于不准确,您可能无法获得与预期相同数量的项目。 如果您正在使用多项式来确定项目的确切数量,这可能是一个真正的问题。

你真正想要的是算术级数; 下面的代码将非常适合intfloatcomplex …以及string和列表。

 def arithmetic_progression(start, step, length): for i in xrange(length): yield start + i * step 

请注意,这个代码比上一个维持运行总数的替代scheme的上一个值处于期望值的公牛咆哮中更有可能。

 >>> 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_range(start, stop, step): assert step > 0.0 total = start compo = 0.0 while total < stop: yield total y = step - compo temp = total + y compo = (temp - total) - y total = temp >>> list(kahan_range(0, 1, 0.0001))[-1] 0.9999 >>> list(kahan_range(0, 3333.3334, 1/3.))[-1] 3333.333333333333 >>> 

当你一起添加浮点数时,通常会有一点点的错误。 range(0.0, 2.2, 1.1) [0.0, 1.1, 2.199999999] range(0.0, 2.2, 1.1)返回[0.0, 1.1] [0.0, 1.1, 2.199999999]还是[0.0, 1.1, 2.199999999] ? 没有严格的分析就没有办法确定。

你发布的代码是一个确定的解决办法,如果你真的需要这个。 只要意识到可能的缺点。

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

  [ (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' 

所以:

 >>> [ .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] 

希望能帮助到你。

可能是因为你不能有一个迭代的一部分。 另外, floats是不精确的。