Как использовать десятичное значение шага ()? - PullRequest
623 голосов
/ 25 января 2009

Есть ли способ перейти между 0 и 1 на 0,1?

Я думал, что смогу сделать это следующим образом, но это не удалось:

for i in range(0, 1, 0.1):
    print i

Вместо этого он говорит, что аргумент шага не может быть нулем, чего я не ожидал.

Ответы [ 33 ]

8 голосов
/ 07 сентября 2012
import numpy as np
for i in np.arange(0, 1, 0.1): 
    print i 
5 голосов
/ 25 января 2009

И если вы делаете это часто, вы можете сохранить сгенерированный список r

r=map(lambda x: x/10.0,range(0,10))
for i in r:
    print i
4 голосов
/ 12 декабря 2013

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

from __future__ import division
from math import log

def xfrange(start, stop, step):

    old_start = start #backup this value

    digits = int(round(log(10000, 10)))+1 #get number of digits
    magnitude = 10**digits
    stop = int(magnitude * stop) #convert from 
    step = int(magnitude * step) #0.1 to 10 (e.g.)

    if start == 0:
        start = 10**(digits-1)
    else:
        start = 10**(digits)*start

    data = []   #create array

    #calc number of iterations
    end_loop = int((stop-start)//step)
    if old_start == 0:
        end_loop += 1

    acc = start

    for i in xrange(0, end_loop):
        data.append(acc/magnitude)
        acc += step

    return data

print xfrange(1, 2.1, 0.1)
print xfrange(0, 1.1, 0.1)
print xfrange(-1, 0.1, 0.1)

Вывод:

[1.0, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9, 2.0]
[0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 1.1]
[-1.0, -0.9, -0.8, -0.7, -0.6, -0.5, -0.4, -0.3, -0.2, -0.1, 0.0]
4 голосов
/ 13 декабря 2012

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

Это согласуется с пустыми результатами набора, как в диапазоне / xrange.

Передача только одного числового значения любой функции вернет стандартный выходной диапазон к целочисленному предельному значению входного параметра (поэтому, если вы зададите 5.5, он вернет диапазон (6).)

Редактировать: приведенный ниже код теперь доступен как пакет на pypi: Franges

## frange.py
from math import ceil
# find best range function available to version (2.7.x / 3.x.x)
try:
    _xrange = xrange
except NameError:
    _xrange = range

def frange(start, stop = None, step = 1):
    """frange generates a set of floating point values over the 
    range [start, stop) with step size step

    frange([start,] stop [, step ])"""

    if stop is None:
        for x in _xrange(int(ceil(start))):
            yield x
    else:
        # create a generator expression for the index values
        indices = (i for i in _xrange(0, int((stop-start)/step)))  
        # yield results
        for i in indices:
            yield start + step*i

## drange.py
import decimal
from math import ceil
# find best range function available to version (2.7.x / 3.x.x)
try:
    _xrange = xrange
except NameError:
    _xrange = range

def drange(start, stop = None, step = 1, precision = None):
    """drange generates a set of Decimal values over the
    range [start, stop) with step size step

    drange([start,] stop, [step [,precision]])"""

    if stop is None:
        for x in _xrange(int(ceil(start))):
            yield x
    else:
        # find precision
        if precision is not None:
            decimal.getcontext().prec = precision
        # convert values to decimals
        start = decimal.Decimal(start)
        stop = decimal.Decimal(stop)
        step = decimal.Decimal(step)
        # create a generator expression for the index values
        indices = (
            i for i in _xrange(
                0, 
                ((stop-start)/step).to_integral_value()
            )
        )  
        # yield results
        for i in indices:
            yield float(start + step*i)

## testranges.py
import frange
import drange
list(frange.frange(0, 2, 0.5)) # [0.0, 0.5, 1.0, 1.5]
list(drange.drange(0, 2, 0.5, precision = 6)) # [0.0, 0.5, 1.0, 1.5]
list(frange.frange(3)) # [0, 1, 2]
list(frange.frange(3.5)) # [0, 1, 2, 3]
list(frange.frange(0,10, -1)) # []
3 голосов
/ 09 февраля 2018

more_itertools - сторонняя библиотека, которая реализует инструмент numeric_range:

import more_itertools as mit


for x in mit.numeric_range(0, 1, 0.1):
    print("{:.1f}".format(x))

выход

0.0
0.1
0.2
0.3
0.4
0.5
0.6
0.7
0.8
0.9

Этот инструмент также работает для Decimal и Fraction.

2 голосов
/ 12 февраля 2016

Это можно сделать с помощью библиотеки Numpy. Функция arange () позволяет выполнять шаги в float. Но он возвращает массив NumPy, который может быть преобразован в список с помощью tolist () для нашего удобства.

for i in np.arange(0, 1, 0.1).tolist():
   print i
2 голосов
/ 12 сентября 2015

Для полноты бутика, функциональное решение:

def frange(a,b,s):
  return [] if s > 0 and a > b or s < 0 and a < b or s==0 else [a]+frange(a+s,b,s)
2 голосов
/ 02 сентября 2015

Чтобы избежать проблемы округления , нужно использовать отдельное число для перемещения по диапазону, который начинается, и половина шаг * впереди * начать 1008 *.

# floating point range
def frange(a, b, stp=1.0):
  i = a+stp/2.0
  while i<b:
    yield a
    a += stp
    i += stp

В качестве альтернативы можно использовать numpy.arange.

2 голосов
/ 25 июня 2010

Вы можете использовать эту функцию:

def frange(start,end,step):
    return map(lambda x: x*step, range(int(start*1./step),int(end*1./step)))
2 голосов
/ 16 февраля 2017

Мой ответ похож на другие, использующие map (), без необходимости использования NumPy и без использования лямбды (хотя вы могли бы). Чтобы получить список значений с плавающей запятой от 0,0 до t_max с шагом dt:

def xdt(n):
    return dt*float(n)
tlist  = map(xdt, range(int(t_max/dt)+1))
...