range()函数是否适用于浮点数?

214

在Python中是否有适用于浮点数的range()等效函数?

>>> range(0.5,5,1.5)
[0, 1, 2, 3, 4]
>>> range(0.5,5,0.5)

Traceback (most recent call last):
  File "<pyshell#10>", line 1, in <module>
    range(0.5,5,0.5)
ValueError: range() step argument must not be zero

2
这些不是分数,而是浮点数。浮点数可能会产生与您预期不同的结果。 - user395760
8
一个快速的解决方法是将整数视为小数,例如:range(5, 50, 5),然后只需将每个数字除以10。 - NullUserException
@delnan - 已更新。为了拥有浮点范围的便利,我愿意接受微小的不准确性。 - Jonathan Livni
2
可能是Python decimal range() step value的重复问题。 - Jonathan Livni
你可以从Python decimal range() step value问题以及它所涉及的frange(), a range function with float increments (ActiveState Code)中找到更多关于这个问题的好坏答案的深入见解。 - nealmcb
显示剩余4条评论
24个回答

0
谈论杞人忧天。 如果您放宽要求,不制作range函数的浮点模拟,而只是创建一个易于在for循环中使用的浮点数列表,则编码简单而健壮。
def super_range(first_value, last_value, number_steps):
    if not isinstance(number_steps, int):
        raise TypeError("The value of 'number_steps' is not an integer.")
    if number_steps < 1:
        raise ValueError("Your 'number_steps' is less than 1.")

    step_size = (last_value-first_value)/(number_steps-1)

    output_list = []
    for i in range(number_steps):
        output_list.append(first_value + step_size*i)
    return output_list

first = 20.0
last = -50.0
steps = 5

print(super_range(first, last, steps))

输出结果将会是:

[20.0, 2.5, -15.0, -32.5, -50.0]

请注意,函数super_range不仅限于浮点数。它可以处理任何定义了运算符+-*/的数据类型,例如complexDecimalnumpy.array
import cmath
first = complex(1,2)
last = complex(5,6)
steps = 5

print(super_range(first, last, steps))

from decimal import *
first = Decimal(20)
last = Decimal(-50)
steps = 5

print(super_range(first, last, steps))

import numpy as np
first = np.array([[1, 2],[3, 4]])
last = np.array([[5, 6],[7, 8]])
steps = 5

print(super_range(first, last, steps))

输出结果将是:

[(1+2j), (2+3j), (3+4j), (4+5j), (5+6j)]
[Decimal('20.0'), Decimal('2.5'), Decimal('-15.0'), Decimal('-32.5'), Decimal('-50.0')]
[array([[1., 2.],[3., 4.]]),
 array([[2., 3.],[4., 5.]]),
 array([[3., 4.],[5., 6.]]),
 array([[4., 5.],[6., 7.]]),
 array([[5., 6.],[7., 8.]])]

0
我之前遇到了同样的问题,无法在y轴上绘制概率。我尝试了以下方法:
list(map(lambda x : x.round(1), np.linspace(0.0, 1.0, num=6)))

这会产生:
[0.0, 0.2, 0.4, 0.6, 0.8, 1.0]

你可以使用 round() 来处理小数部分。

-1

当然会有一些舍入误差,所以这不是完美的,但这通常是我用于不需要高精度的应用程序。如果您想使其更准确,可以添加一个额外的参数来指定如何处理舍入误差。也许传递一个舍入函数可能会使其可扩展,并允许程序员指定如何处理舍入误差。

arange = lambda start, stop, step: [i + step * i for i in range(int((stop - start) / step))]

如果我写下以下代码:
arange(0, 1, 0.1)

它将输出:

[0.0, 0.1, 0.2, 0.30000000000000004, 0.4, 0.5, 0.6000000000000001, 0.7000000000000001, 0.8, 0.9]

-2

这里有几个答案没有处理简单的边缘情况,例如负步长、错误的起始点、终止等。下面是一个版本,它可以正确地处理许多这些情况,从而产生与本地range()相同的行为:

def frange(start, stop=None, step=1):
  if stop is None:
    start, stop = 0, start
  steps = int((stop-start)/step)
  for i in range(steps):
    yield start
    start += step  

请注意,这将像本地的range一样在step=0时出错。一个区别是本地的range返回可索引和可逆转的对象,而上面的代码则不会。
您可以在此处尝试运行此代码并测试用例。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接