具有float类型的步长的范围

Alb*_*ert 47 python range

文档基本上说range必须完全像这个实现一样(对于正面step):

def range(start, stop, step):
  x = start
  while True:
    if x >= stop: return
    yield x
    x += step
Run Code Online (Sandbox Code Playgroud)

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

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


更具体一点:我如何以一种很好的方式将这个C代码直接翻译成Python(即不仅仅是通过while-loop手动完成):

for(float x = 0; x < 10; x += 0.5f) { /* ... */ }
Run Code Online (Sandbox Code Playgroud)

Kat*_*iel 51

你可以用numpy.arange.

编辑:文档更喜欢numpy.linspace.感谢@Droogans注意到=)

  • _first paragraph_表示:当使用非整数步骤(例如0.1)时,结果通常不一致.对于这些情况,最好使用[`linspace`](http://docs.scipy.org/doc/numpy/reference/generated/numpy.linspace.html?highlight=linspace#numpy.linspace). (3认同)
  • 注意`linspace`有不同的接口. (2认同)

Zar*_*nen 35

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

range(0, 0.4, 0.1)
Run Code Online (Sandbox Code Playgroud)

你可能期望输出

[0, 0.1, 0.2, 0.3]
Run Code Online (Sandbox Code Playgroud)

但你实际上得到的东西

[0, 0.1, 0.2000000001, 0.3000000001]
Run Code Online (Sandbox Code Playgroud)

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

尽管如此,如果你想要一个用于花车的量程发生器,你可以自己动手.

def xfrange(start, stop, step):
    i = 0
    while start + i * step < stop:
        yield start + i * step
        i += 1
Run Code Online (Sandbox Code Playgroud)

  • 您正在累积舍入误差。请改用这个:` i = 0; r = 开始而 r &lt; 停止:i += 1;r = 开始 + i * 步;产量 r` (2认同)

mar*_*fer 13

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

  • 如果你的"范围"有很多数字并且0.1的"步长"较小,比如说.00000001,那么这将不起作用,并且脚本将在大多数计算机上挂起.我们需要一些模拟xrange做什么的东西.我们需要一个可迭代/生成器,而不是list comprehension.fxrange范围在这种情况下效果更好. (3认同)

Joh*_*hin 6

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

你真正想要的是算术级数; 以下代码将非常愉快地工作int,float以及complex...和字符串,以及列表......

def arithmetic_progression(start, step, length):
    for i in xrange(length):
        yield start + i * step
Run Code Online (Sandbox Code Playgroud)

请注意,与保持总计的任何替代方案相比,此代码更有可能使您的最后一个值处于预期值的公牛咆哮之内.

>>> 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)
Run Code Online (Sandbox Code Playgroud)

更正:这是一个竞争性的运行总计小工具:

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
>>>
Run Code Online (Sandbox Code Playgroud)


Mar*_*som 5

将浮点数一起添加时,通常会出现一些错误.会range(0.0, 2.2, 1.1)回来[0.0, 1.1]还是[0.0, 1.1, 2.199999999]?没有严格的分析就没有办法确定.

如果您真的需要,您发布的代码是一个好的解决方法.请注意可能存在的缺点.