在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
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
不仅限于浮点数。它可以处理任何定义了运算符+
、-
、*
和/
的数据类型,例如complex
、Decimal
和numpy.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.]])]
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()
来处理小数部分。当然会有一些舍入误差,所以这不是完美的,但这通常是我用于不需要高精度的应用程序。如果您想使其更准确,可以添加一个额外的参数来指定如何处理舍入误差。也许传递一个舍入函数可能会使其可扩展,并允许程序员指定如何处理舍入误差。
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]
这里有几个答案没有处理简单的边缘情况,例如负步长、错误的起始点、终止等。下面是一个版本,它可以正确地处理许多这些情况,从而产生与本地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返回可索引和可逆转的对象,而上面的代码则不会。
range(5, 50, 5)
,然后只需将每个数字除以10。 - NullUserException