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

Есть ли эквивалент range() для float в 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 

    12 Solutions collect form web for “range () для поплавков”

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

     def frange(x, y, jump): while x < y: yield x x += jump 

    Как отмечают комментарии, это может привести к непредсказуемым результатам, таким как:

     >>> list(frange(0, 100, 0.1))[-1] 99.9999999999986 

    Чтобы получить ожидаемый результат, вы можете использовать один из других ответов в этом вопросе или, как упоминалось в @Tadhg, вы можете использовать decimal.Decimal в качестве аргумента jump . Обязательно инициализируйте его строкой, а не плавающей точкой.

     >>> import decimal >>> list(frange(0, 100, decimal.Decimal('0.1')))[-1] Decimal('99.9') 

    Или даже:

     import decimal def drange(x, y, jump): while x < y: yield float(x) x += decimal.Decimal(jump) 

    А потом:

     >>> list(drange(0, 100, '0.1'))[-1] 99.9 

    Вы можете использовать:

     [x / 10.0 for x in range(5, 50, 15)] 

    или используйте лямбда / карту:

     map(lambda x: x/10.0, range(5, 50, 15)) 

    Я использовал numpy.arange но имел некоторые сложности, контролирующие количество возвращаемых элементов из-за ошибок с плавающей запятой. Итак, теперь я использую linspace , например:

     >>> import numpy >>> numpy.linspace(0, 10, num=4) array([ 0. , 3.33333333, 6.66666667, 10. ]) 

    Pylab имеет frange (обертка, фактически, для matplotlib.mlab.frange ):

     >>> import pylab as pl >>> pl.frange(0.5,5,0.5) array([ 0.5, 1. , 1.5, 2. , 2.5, 3. , 3.5, 4. , 4.5, 5. ]) 

    С нетерпением оцененный ( range 2.x):

     [x * .5 for x in range(10)] 

    Ленько оценивается (2.x xrange , range 3.x):

     itertools.imap(lambda x: x * .5, xrange(10)) # or range(10) as appropriate 

    С другой стороны:

     itertools.islice(itertools.imap(lambda x: x * .5, itertools.count()), 10) # without applying the `islice`, we get an infinite stream of half-integers. 

    используя itertools : лениво оцениваемый диапазон с плавающей запятой:

     >>> from itertools import count, takewhile >>> def frange(start, stop, step): return takewhile(lambda x: x< stop, count(start, step)) >>> list(frange(0.5, 5, 1.5)) # [0.5, 2.0, 3.5] 

    Нет такой встроенной функции, но вы можете использовать следующий (код Python 3), чтобы сделать работу такой же безопасной, как позволяет Python.

     from fractions import Fraction def frange(start, stop, jump, end=False, via_str=False): """ Equivalent of Python 3 range for decimal numbers. Notice that, because of arithmetic errors, it is safest to pass the arguments as strings, so they can be interpreted to exact fractions. >>> assert Fraction('1.1') - Fraction(11, 10) == 0.0 >>> assert Fraction( 0.1 ) - Fraction(1, 10) == Fraction(1, 180143985094819840) Parameter `via_str` can be set to True to transform inputs in strings and then to fractions. When inputs are all non-periodic (in base 10), even if decimal, this method is safe as long as approximation happens beyond the decimal digits that Python uses for printing. For example, in the case of 0.1, this is the case: >>> assert str(0.1) == '0.1' >>> assert '%.50f' % 0.1 == '0.10000000000000000555111512312578270211815834045410' If you are not sure whether your decimal inputs all have this property, you are better off passing them as strings. String representations can be in integer, decimal, exponential or even fraction notation. >>> assert list(frange(1, 100.0, '0.1', end=True))[-1] == 100.0 >>> assert list(frange(1.0, '100', '1/10', end=True))[-1] == 100.0 >>> assert list(frange('1', '100.0', '.1', end=True))[-1] == 100.0 >>> assert list(frange('1.0', 100, '1e-1', end=True))[-1] == 100.0 >>> assert list(frange(1, 100.0, 0.1, end=True))[-1] != 100.0 >>> assert list(frange(1, 100.0, 0.1, end=True, via_str=True))[-1] == 100.0 """ if via_str: start = str(start) stop = str(stop) jump = str(jump) start = Fraction(start) stop = Fraction(stop) jump = Fraction(jump) while start < stop: yield float(start) start += jump if end and start == stop: yield(float(start)) 

    Вы можете проверить все это, выполнив несколько утверждений:

     assert Fraction('1.1') - Fraction(11, 10) == 0.0 assert Fraction( 0.1 ) - Fraction(1, 10) == Fraction(1, 180143985094819840) assert str(0.1) == '0.1' assert '%.50f' % 0.1 == '0.10000000000000000555111512312578270211815834045410' assert list(frange(1, 100.0, '0.1', end=True))[-1] == 100.0 assert list(frange(1.0, '100', '1/10', end=True))[-1] == 100.0 assert list(frange('1', '100.0', '.1', end=True))[-1] == 100.0 assert list(frange('1.0', 100, '1e-1', end=True))[-1] == 100.0 assert list(frange(1, 100.0, 0.1, end=True))[-1] != 100.0 assert list(frange(1, 100.0, 0.1, end=True, via_str=True))[-1] == 100.0 assert list(frange(2, 3, '1/6', end=True))[-1] == 3.0 assert list(frange(0, 100, '1/3', end=True))[-1] == 100.0 

    Код доступен на GitHub

    Я помог добавить функцию numeric_range в пакет more-itertools .

    more_itertools.numeric_range(start, stop, step) действует как встроенный диапазон функций, но может обрабатывать типы float, Decimal и Fraction.

     >>> from more_itertools import numeric_range >>> tuple(numeric_range(.1, 5, 1)) (0.1, 1.1, 2.1, 3.1, 4.1) 

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

     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 

    Решение без зависимостей numpy и др. Было предоставлено kichik, но из- за арифметики с плавающей запятой оно часто ведет себя неожиданно. Как отмечено мной и blubberdiblub , дополнительные элементы легко проникают в результат. Например, naive_frange(0.0, 1.0, 0.1) даст 0.999... качестве последнего значения и, таким образом, даст всего 11 значений.

    Здесь приведена надежная версия:

     def frange(x, y, jump=1.0): '''Range for floats.''' i = 0.0 x = float(x) # Prevent yielding integers. x0 = x epsilon = jump / 2.0 yield x # yield always first value while x + epsilon < y: i += 1.0 x = x0 + i * jump yield x 

    Поскольку умножение, ошибки округления не накапливаются. Использование epsilon заботится о возможной ошибке округления умножения, хотя проблемы, конечно, могут возрастать в очень малых и очень больших концах. Теперь, как и ожидалось:

     > a = list(frange(0.0, 1.0, 0.1)) > a[-1] 0.9 > len(a) 10 

    И с несколько большим числом:

     > b = list(frange(0.0, 1000000.0, 0.1)) > b[-1] 999999.9 > len(b) 10000000 

    Код также доступен как GitHub Gist .

     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) 

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

    Есть ли эквивалент range () для float в 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 
    Python - лучший язык программирования в мире.