Range () для поплавков - PullRequest
       50

Range () для поплавков

115 голосов
/ 01 сентября 2011

Есть ли range() эквивалент для чисел с плавающей точкой в ​​Python?

>>> 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

Ответы [ 16 ]

1 голос
/ 14 ноября 2018

Более простая версия без библиотек

Ой, черт возьми - я добавлю простую версию без библиотек.Не стесняйтесь улучшать его [*]:

def frange(start=0, stop=1, jump=0.1):
    nsteps = int((stop-start)/jump)
    dy = stop-start
    # f(i) goes from start to stop as i goes from 0 to nsteps
    return [start + float(i)*dy/nsteps for i in range(nsteps)]

Основная идея заключается в том, что nsteps - это количество шагов, которые помогут вам от начала и до конца, а range(nsteps) всегда выдает целые числа, чтобы не было потерьточности.Последний шаг - отобразить [0..nsteps] линейно на [start..stop].

edit

Если, как alancalvitti , вы хотите сериючтобы получить точное рациональное представление, вы всегда можете использовать Fractions :

from fractions import Fraction

def rrange(start=0, stop=1, jump=0.1):
    nsteps = int((stop-start)/jump)
    return [Fraction(i, nsteps) for i in range(nsteps)]

[*] В частности, frange() возвращает список, а не генератор.Но этого хватило для моих нужд.

0 голосов
/ 02 марта 2019

Здесь есть несколько ответов, которые не обрабатывают простые крайние случаи, такие как отрицательный шаг, неправильный старт, остановка и т. Д. Вот версия, которая правильно обрабатывает многие из этих случаев, давая то же поведение, что и нативный 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  

Обратите внимание, что это приведет к ошибке out step = 0, так же как и к нативному range. Одно из отличий состоит в том, что собственный диапазон возвращает объект, который индексируется и может быть обратимым, а выше - нет.

Вы можете играть с этим кодом и тестовыми примерами здесь.

0 голосов
/ 14 октября 2017

Я думаю, что есть очень простой ответ, который действительно эмулирует все функции диапазона, кроме как с плавающей точкой, так и с целым числом. В этом решении вы просто предполагаете, что ваше приближение по умолчанию равно 1e-7 (или выбранное вами), и вы можете изменить его при вызове функции.

def drange(start,stop=None,jump=1,approx=7): # Approx to 1e-7 by default
  '''
  This function is equivalent to range but for both float and integer
  '''
  if not stop: # If there is no y value: range(x)
      stop= start
      start= 0
  valor= round(start,approx)
  while valor < stop:
      if valor==int(valor):
          yield int(round(valor,approx))
      else:
          yield float(round(valor,approx))
      valor += jump
  for i in drange(12):
      print(i)
0 голосов
/ 12 января 2017

Есть ли эквивалент в диапазоне () для чисел с плавающей точкой в ​​Python? НЕТ Используйте это:

def f_range(start, end, step):
    a = range(int(start/0.01), int(end/0.01), int(step/0.01))
    var = []
    for item in a:
        var.append(item*0.01)
    return var
0 голосов
/ 12 января 2017
def Range(*argSequence):
    if len(argSequence) == 3:
        imin = argSequence[0]; imax = argSequence[1]; di = argSequence[2]
        i = imin; iList = []
        while i <= imax:
            iList.append(i)
            i += di
        return iList
    if len(argSequence) == 2:
        return Range(argSequence[0], argSequence[1], 1)
    if len(argSequence) == 1:
        return Range(1, argSequence[0], 1)

Обратите внимание, что первая буква диапазона - это заглавная.Этот метод именования не рекомендуется для функций в Python.Вы можете изменить Range на что-то вроде drange или frange, если хотите.Функция «Range» ведет себя так, как вы хотите.Вы можете проверить это руководство здесь [http://reference.wolfram.com/language/ref/Range.html].

0 голосов
/ 19 ноября 2015

Я написал функцию, которая возвращает кортеж из диапазона чисел с плавающей запятой двойной точности без десятичных разрядов, кроме сотых.это был просто вопрос разбора значений диапазона, таких как строки, и разделения лишнего.Я использую его для отображения диапазонов, чтобы выбрать из пользовательского интерфейса.Я надеюсь, что кто-то найдет это полезным.

def drange(start,stop,step):
    double_value_range = []
    while start<stop:
        a = str(start)
        a.split('.')[1].split('0')[0]
        start = float(str(a))
        double_value_range.append(start)
        start = start+step
    double_value_range_tuple = tuple(double_value_range)
   #print double_value_range_tuple
    return double_value_range_tuple
...