范围与浮动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)]
浮点的问题在于,由于不准确,您可能无法获得与预期相同数量的项目。 如果您正在使用多项式来确定项目的确切数量,这可能是一个真正的问题。
你真正想要的是算术级数; 下面的代码将非常适合int
, float
和complex
…以及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
是不精确的。