蟒蛇-范围与典型的步骤

这个问题已经在这里有了答案:

  • 如何使用十进制range()步长值?                                     33个答案

该文档基本上说while必须与该实现完全相同(对于正数step):

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

它还说它的参数必须是整数。 这是为什么? 如果step是浮点数,该定义不是也完全有效吗?

就我而言,我是。 需要一个while函数,该函数接受一个float类型作为其step参数。 Python中是否有任何工具,还是我需要实现自己的工具?


更具体地说:如何将这种C代码以一种不错的方式直接转换为Python(即,不仅通过while循环手动完成此操作):

for(float x = 0; x < 10; x += 0.5f) { /* ... */ }
Albert asked 2020-02-29T09:06:57Z
8个解决方案
51 votes

您可以使用numpy.linspace

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

Katriel answered 2020-02-29T09:07:47Z
35 votes

一种解释可能是浮点取整问题。 例如,如果您可以致电

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
Zarkonnen answered 2020-02-29T09:08:25Z
13 votes

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

mariana soffer answered 2020-02-29T09:08:45Z
6 votes

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

您真正想要的是算术级数; 以下代码将非常愉快地适用于2768737928242267267136、floatcomplex ...以及字符串和列表...

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_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
>>>
John Machin answered 2020-02-29T09:09:19Z
5 votes

将浮点数加在一起时,通常会出现一些错误。 range(0.0, 2.2, 1.1)是否会返回[0.0, 1.1][0.0, 1.1, 2.199999999]? 没有严格的分析是无法确定的。

如果确实需要,发布的代码可以解决。 请注意可能存在的缺点。

Mark Ransom answered 2020-02-29T09:09:44Z
3 votes

这是一个特例,可能就足够了:

 [ (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]
ntg answered 2020-02-29T09:10:13Z
1 votes

这就是我要使用的:

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]

希望能帮助到你。

Andrey answered 2020-02-29T09:10:41Z
-1 votes

可能是因为您无法拥有可迭代的部分。 另外,floats也不够精确。

Tim McNamara answered 2020-02-29T09:11:03Z
translate from https://stackoverflow.com:/questions/4189766/range-with-step-of-type-float