Есть ли способ перейти между 0 и 1 на 0,1?
Я думал, что смогу сделать это следующим образом, но это не удалось:
for i in range(0, 1, 0.1):
print i
Вместо этого он говорит, что аргумент шага не может быть нулем, чего я не ожидал.
python
floating-point
range
Эван Фосмарк
источник
источник
itertools.takewhile
иitertools.count
. Это не лучше, чемdrange
с точки зрения производительности.seq
инструмент в GNU coreutils позволяет обходитьсяseq 0 0.1 1
без ошибок округления!seq
использует Clong double
тип внутренне, и это с учетом ошибок округления. Например, на моей машине,seq 0 0.1 1
дает1
как последний вывод (как и ожидалось), ноseq 1 0.1 2
дает1.9
как последний вывод (а не ожидаемый2
).itertools.takewhile(lambda x: (x+0.05)<1, itertools.count(0,0.1))
илиitertools.islice(itertools.count(0,0.1), 10)
(после того, как вы это сделалиimport itertools
), хотя я не проверял, что является более эффективнымОтветы:
Вместо того, чтобы использовать десятичный шаг напрямую, гораздо безопаснее выразить это в виде количества точек, которые вы хотите получить. В противном случае ошибка округления с плавающей точкой может привести к неверному результату.
Вы можете использовать функцию linspace из библиотеки NumPy (которая не является частью стандартной библиотеки, но ее относительно легко получить).
linspace
возвращает количество точек для возврата, а также позволяет указать, следует ли включать правильную конечную точку:Если вы действительно хотите использовать значение шага с плавающей точкой, вы можете, с помощью
numpy.arange
.Ошибка округления чисел с плавающей точкой будет вызывать проблемы, хотя. Вот простой случай, когда ошибка округления приводит
arange
к созданию массива длины 4, когда он должен производить только 3 числа:источник
np.linspace(1.,1.3,4)
иnp.arange(1.,1.3,0.1)
[start,stop)
(т.е. исключаяstop
), поэтому не стоит ожидать, что 1.3 будет включено в список. Посмотрите этот вопрос, почему он все еще включен и что с этим делать.Range () Python может делать только целые числа, а не с плавающей точкой. В вашем конкретном случае вы можете использовать понимание списка вместо:
(Замените вызов range этим выражением.)
В более общем случае вы можете написать пользовательскую функцию или генератор.
источник
(x * 0.1 for x in range(0, 10))
,x/10
вместоx * 0.1
: D Ничего особенного на самом деле, но некоторые цифры там будут более точными, например, для3*0.1
вас0.30000000000000004
, в то время как для 3/10 вы получаете0.3
:)from __future__ import division; 3/10
возвращает 0.3. Это поведение по умолчанию в Python 3.x.Основываясь на 'xrange ([start], stop [, step])' , вы можете определить генератор, который принимает и производит любой тип, который вы выберете (придерживайтесь типов, поддерживающих
+
и<
):источник
Увеличьте величину
i
цикла, а затем уменьшите ее, когда вам это нужно.РЕДАКТИРОВАТЬ: я честно не могу вспомнить, почему я думал, что это будет работать синтаксически
Это должно иметь желаемый результат.
источник
for i * 100 in range(0, 100, 10)
: SyntaxError: невозможно назначить операторуscipy
имеет встроенную функцию,arange
которая обобщаетrange()
конструктор Python для удовлетворения ваших требований обработки с плавающей точкой.from scipy import arange
источник
arange
вы можете найти в numpy:>>> import scipy >>> import numpy >>> numpy.arange is scipy.arange
вернетсяTrue
.from nump import arange as range
Думаю, NumPy немного излишне.
Вообще говоря, чтобы сделать шаг за
1/x
вверх , чтобыy
вы могли бы сделать(
1/x
при тестировании меньше шума при округлении).источник
Подобно функции R
seq
, эта функция возвращает последовательность в любом порядке, учитывая правильное значение шага. Последнее значение равно значению остановки.Результаты
источник
seq(0.5, 3.0)
возвращается[0.5, 1.5, 2.5, 3.5]
. Чтобы избежать последних записей быть вне диапазона, заменитеn = int(round(...
сn = int(floor(...
с линиейfrom math import floor
в верхней части (вышеdef seq(...
).floor
используется,seq(0.2, 0.9, 0.1)
не достигнет правильной конечной точки и вернется[0.2, 0.30000000000000004, 0.4, 0.5, 0.6000000000000001, 0.7, 0.8]
Боюсь, встроенная функция range () возвращает последовательность целочисленных значений, поэтому вы не можете использовать ее для выполнения десятичного шага.
Я бы сказал, просто используйте цикл while:
Если вам интересно, Python конвертирует ваш 0.1 в 0, поэтому он говорит вам, что аргумент не может быть нулевым.
источник
.1
10 раз - это не то же самое, что добавление1
! docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.htmlВот решение с использованием itertools :
Пример использования:
источник
в Python 2.7x дает вам результат:
но если вы используете:
дает вам желаемое:
источник
источник
И если вы делаете это часто, вы можете сохранить сгенерированный список
r
источник
more_itertools
сторонняя библиотека, которая реализуетnumeric_range
инструмент:Вывод
Этот инструмент также работает для
Decimal
иFraction
.источник
Мои версии используют оригинальную функцию диапазона для создания мультипликативных индексов для сдвига. Это позволяет использовать тот же синтаксис для исходной функции диапазона. Я сделал две версии, одну с использованием float, а другую с использованием Decimal, потому что я обнаружил, что в некоторых случаях я хотел избежать дрейфа округления, представленного арифметикой с плавающей запятой.
Это согласуется с пустыми результатами набора, как в range / xrange.
Передача только одного числового значения в любую функцию вернет стандартный выходной диапазон к целочисленному предельному значению входного параметра (поэтому, если вы зададите 5.5, он вернет диапазон (6).)
Изменить: код ниже теперь доступен в виде пакета на Pypi: Franges
источник
frange
работать, если остановка естьNone
? Эта часть кода даже не учитывает размер шага.range
имеет две подписи:,range(stop)
которая предполагает значение по умолчаниюstart=0, step=1
, иrange(start, stop, step)
, где не делается никаких предположений.frange
отражает это. При использованииrange(stop)
подписи обаfrange
иdrange
начинаются с 0, и увеличиваются на 1, поэтому их поведение идентично обычномуrange(stop)
поведению со стопом, округленным до ближайшего целого числа.Это мое решение, чтобы получить диапазоны с плавающими шагами.
При использовании этой функции нет необходимости ни импортировать numpy, ни устанавливать его.
Я уверен, что это можно улучшить и оптимизировать. Не стесняйтесь делать это и размещать здесь.
Выход:
источник
Для полноты бутика, функциональное решение:
источник
Вы можете использовать эту функцию:
источник
list(frange(99.8, 100.1, 0.1)) => [99.7, 99.80000000000001, 99.9]
Хитрость , чтобы избежать округления проблемы заключается в использовании отдельного номера для перемещения по диапазону, который начинается и половина шаг впереди старта .
В качестве альтернативы
numpy.arange
можно использовать.источник
Это можно сделать с помощью библиотеки Numpy. Функция arange () позволяет выполнять шаги в float. Но он возвращает пустой массив, который может быть преобразован в список с помощью tolist () для нашего удобства.
источник
Мой ответ похож на другие, использующие map (), без необходимости использования NumPy и без использования лямбды (хотя вы могли бы). Чтобы получить список значений с плавающей точкой от 0,0 до t_max с шагом dt:
источник
Удивленный, никто еще не упомянул рекомендуемое решение в документации по Python 3 :
После определения, рецепт прост в использовании и не требует
numpy
каких-либо других внешних библиотек, но функционирует какnumpy.linspace()
. Обратите внимание, что вместоstep
аргумента третийnum
аргумент задает количество желаемых значений, например:Я цитирую модифицированную версию полного рецепта Python 3 от Эндрю Барнерта ниже:
источник
Чтобы противостоять проблемам точности поплавка, вы можете использовать
Decimal
модуль .Это требует дополнительных усилий для преобразования
Decimal
изint
илиfloat
во время написания кода, но вместо этого вы можете передатьstr
и изменить функцию, если такое удобство действительно необходимо.Пример выходов -
источник
Decimal
входами,np.arange
работает так же:np.arange(Decimal('-2.0'), Decimal('2.0'), Decimal('0.1'))
Добавьте автокоррекцию для возможности неверного знака на шаге:
источник
Мое решение:
источник
Лучшее решение: нет ошибки округления
_________________________________________________________________________________
_________________________________________________________________________________
Или для заданного диапазона вместо заданных точек данных (например, непрерывная функция) используйте:
Для реализации функции: заменить
x / pow(step, -1)
наf( x / pow(step, -1) )
и определитьf
.Например:
источник
запуск и остановка включаются, а не один или другой (обычно остановка исключается) и без импорта и с использованием генераторов
источник
Я знаю, что опаздываю на вечеринку здесь, но вот тривиальное генераторное решение, которое работает в 3.6:
тогда вы можете назвать его так же, как оригинал
range()
... обработки ошибок нет, но дайте мне знать, если есть ошибка, которая может быть разумно обнаружена, и я обновлю. или вы можете обновить его. это StackOverflow.источник
Вот мое решение, которое отлично работает с float_range (-1, 0, 0.01) и работает без ошибок представления с плавающей запятой. Это не очень быстро, но отлично работает:
источник
Я только новичок, но у меня была такая же проблема при моделировании некоторых вычислений. Вот как я пытался решить эту проблему, которая, кажется, работает с десятичными шагами.
Я также довольно ленив, и поэтому мне было трудно написать свою собственную функцию диапазона.
В основном то , что я сделал это изменило мое
xrange(0.0, 1.0, 0.01)
кxrange(0, 100, 1)
и используется деление на100.0
внутри цикла. Меня также беспокоило, будут ли ошибки округления. Поэтому я решил проверить, есть ли такие. Теперь я слышал, что если, например,0.01
из расчета не совсем поплавок,0.01
сравнивающий их должен вернуть False (если я ошибаюсь, пожалуйста, дайте мне знать).Поэтому я решил проверить, будет ли мое решение работать для моего диапазона, выполнив короткий тест:
И это напечатало True для каждого.
Теперь, если я все понял неправильно, пожалуйста, дайте мне знать.
источник
Этот лайнер не будет загромождать ваш код. Знак параметра шага важен.
источник