it-swarm.com.de

Wie verwende ich einen Dezimalbereich () -Schrittwert?

Gibt es eine Möglichkeit zwischen 0 und 1 um 0,1 zu wechseln? 

Ich dachte, ich könnte das wie folgt machen, aber es schlug fehl:

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

Stattdessen heißt es, dass das Schrittargument nicht Null sein kann, was ich nicht erwartet hatte.

582
Evan Fosmark

Anstatt einen Dezimalschritt direkt zu verwenden, ist es viel sicherer, dies in Bezug auf die Anzahl der gewünschten Punkte auszudrücken. Andernfalls führt der Rundungsfehler bei Gleitkommazahlen wahrscheinlich zu einem falschen Ergebnis.

Sie können die linspace-Funktion aus der Bibliothek NumPy verwenden (die nicht zur Standardbibliothek gehört, aber relativ einfach zu erhalten ist). linspace benötigt eine Reihe von Punkten, um zurückzukehren, und Sie können außerdem angeben, ob der richtige Endpunkt eingefügt werden soll:

>>> np.linspace(0,1,11)
array([ 0. ,  0.1,  0.2,  0.3,  0.4,  0.5,  0.6,  0.7,  0.8,  0.9,  1. ])
>>> np.linspace(0,1,10,endpoint=False)
array([ 0. ,  0.1,  0.2,  0.3,  0.4,  0.5,  0.6,  0.7,  0.8,  0.9])

Wenn Sie wirklich einen Fließkomma-Schrittwert verwenden möchten, können Sie dies mit numpy.arange tun.

>>> import numpy as np
>>> np.arange(0.0, 1.0, 0.1)
array([ 0. ,  0.1,  0.2,  0.3,  0.4,  0.5,  0.6,  0.7,  0.8,  0.9])

Gleitkomma-Rundungsfehler wird verursachen jedoch Probleme Hier ist ein einfacher Fall, bei dem ein Rundungsfehler dazu führt, dass arange ein Array mit Länge 4 erzeugt, wenn nur 3 Zahlen erzeugt werden:

>>> numpy.arange(1, 1.3, 0.1)
array([1. , 1.1, 1.2, 1.3])
726
Andrew Jaffe

Pythons range () kann nur Ganzzahlen und keine Gleitkommazahlen ausführen. In Ihrem speziellen Fall können Sie stattdessen ein Listenverständnis verwenden:

[x * 0.1 for x in range(0, 10)]

(Ersetzen Sie den Aufruf durch diesen Ausdruck in den Bereich.) 

Für den allgemeineren Fall möchten Sie möglicherweise eine benutzerdefinierte Funktion oder einen Generator schreiben.

178
user25148

Aufbauend auf 'xrange ([start], stop [ step])' können Sie einen Generator definieren, der jeden von Ihnen ausgewählten Typ akzeptiert und produziert (bleiben Sie dabei bei Typen, die + und < unterstützen)

>>> def drange(start, stop, step):
...     r = start
...     while r < stop:
...         yield r
...         r += step
...         
>>> i0=drange(0.0, 1.0, 0.1)
>>> ["%g" % x for x in i0]
['0', '0.1', '0.2', '0.3', '0.4', '0.5', '0.6', '0.7', '0.8', '0.9', '1']
>>> 
143
gimel

Erhöhen Sie die Größe von i für die Schleife und reduzieren Sie sie dann, wenn Sie sie benötigen.

for i * 100 in range(0, 100, 10):
    print i / 100.0

EDIT: Ich kann mich ehrlich nicht erinnern, warum ich dachte, dass das syntaktisch funktionieren würde

for i in range(0, 11, 1):
    print i / 10.0

Das sollte den gewünschten Output haben. 

31
cmsjr

scipy verfügt über eine integrierte Funktion arange, die den range()-Konstruktor von Python so verallgemeinert, dass er Ihre Anforderungen an die Float-Verarbeitung erfüllt. 

from scipy import arange

22
Catherine Ray

NumPy ist ein bisschen übertrieben, denke ich.

[p/10 for p in range(0, 10)]
[0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9]

Im Allgemeinen würden Sie eine Schritt-zu -1/x-Anweisung bis zu y ausführen

x=100
y=2
[p/x for p in range(0, int(x*y))]
[0.0, 0.01, 0.02, 0.03, ..., 1.97, 1.98, 1.99]

(1/x erzeugte beim Testen weniger Rundungsgeräusche).

21
Kalle

Ähnlich wie die Funktion Rsseq gibt diese eine Sequenz in beliebiger Reihenfolge zurück, wenn der richtige Schrittwert angegeben ist. Der letzte Wert entspricht dem Stoppwert. 

def seq(start, stop, step=1):
    n = int(round((stop - start)/float(step)))
    if n > 1:
        return([start + step*i for i in range(n+1)])
    Elif n == 1:
        return([start])
    else:
        return([])

Ergebnisse

seq(1, 5, 0.5)

[1,0, 1,5, 2,0, 2,5, 3,0, 3,5, 4,0, 4,5, 5,0]

seq(10, 0, -1)

[10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0]

seq(10, 0, -2)

[10, 8, 6, 4, 2, 0]

seq(1, 1)

[1]

16
zeferino

Die eingebaute Funktion range () gibt eine Folge von Integer-Werten zurück, leider können Sie diese Funktion nicht für einen Dezimalschritt verwenden. 

Ich würde sagen, verwenden Sie einfach eine while-Schleife:

i = 0.0
while i <= 1.0:
    print i
    i += 0.1

Wenn Sie neugierig sind, konvertiert Python Ihre 0,1 in 0, weshalb es Ihnen sagt, dass das Argument nicht Null sein kann.

11
Dana

Hier ist eine Lösung mit itertools :

import itertools

def seq(start, end, step):
    if step == 0:
        raise ValueError("step must not be 0")
    sample_count = int(abs(end - start) / step)
    return itertools.islice(itertools.count(start, step), sample_count)

Verwendungsbeispiel:

for i in seq(0, 1, 0.1):
    print(i)
10
Pramod
import numpy as np
for i in np.arange(0, 1, 0.1): 
    print i 
8
Raja
[x * 0.1 for x in range(0, 10)] 

in Python 2.7x erhalten Sie das Ergebnis von:

[0,0, 0,1, 0,2, 0,30000000000000004, 0,4, 0,5, 0,6000000000000001, 0,7000000000000001, 0,8, 0,9]

aber wenn Sie verwenden:

[ round(x * 0.1, 1) for x in range(0, 10)]

gibt dir das gewünschte:

[0,0, 0,1, 0,2, 0,3, 0,4, 0,5, 0,6, 0,7, 0,8, 0,9]

8
Nik

Wenn Sie dies häufig tun, möchten Sie möglicherweise die generierte Liste speichern r

r=map(lambda x: x/10.0,range(0,10))
for i in r:
    print i
5
RSabet

Dies ist meine Lösung, um Bereiche mit Schwimmerschritten zu erhalten.
Mit dieser Funktion muss weder numpy importiert noch installiert werden.
Ich bin mir ziemlich sicher, dass es verbessert und optimiert werden kann. Fühlen Sie sich frei, es zu tun und hier zu posten.

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)

Die Ausgabe ist:

[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
Carlos Vega

Meine Versionen verwenden die ursprüngliche Bereichsfunktion, um multiplikative Indizes für die Schicht zu erstellen. Dies ermöglicht dieselbe Syntax wie die ursprüngliche Bereichsfunktion .. Ich habe zwei Versionen erstellt, eine mit Float und eine mit Decimal, da ich festgestellt habe, dass ich in manchen Fällen die von der Fließkomma-Arithmetik eingeführte Abrundungsdrift vermeiden wollte.

Es ist konsistent mit leeren Mengenergebnissen wie in Bereich/Bereich.

Wenn nur ein einzelner numerischer Wert an eine der Funktionen übergeben wird, wird die Standardbereichsausgabe auf den ganzzahligen Höchstwert des Eingabeparameters zurückgesetzt (wenn Sie also 5,5 eingeben, wird der Bereich (6) zurückgegeben).

Edit: Der folgende Code ist jetzt als Paket auf pypi verfügbar: 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)) # []
4
Nisan.H

more_itertools ist eine Bibliothek eines Drittanbieters, die ein numeric_range tool implementiert:

import more_itertools as mit


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

Ausgabe

0.0
0.1
0.2
0.3
0.4
0.5
0.6
0.7
0.8
0.9

Dieses Tool funktioniert auch für Decimal und Fraction .

3
pylang

Meine Antwort ist ähnlich wie bei anderen, die map () verwenden, ohne NumPy zu verwenden und ohne Lambda (obwohl Sie es könnten). Um eine Liste der Float-Werte von 0,0 bis t_max in Schritten von dt zu erhalten:

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

Sie können diese Funktion verwenden:

def frange(start,end,step):
    return map(lambda x: x*step, range(int(start*1./step),int(end*1./step)))
2
user376536

Für die Vollständigkeit der Boutique eine funktionale Lösung:

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

Der Trick zur Vermeidung von Abrundungsproblem ist die Verwendung einer separaten Nummer, um sich durch den Bereich zu bewegen, der beginnt und die Hälfte der Schritt vor Start .

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

Alternativ kann numpy.arange verwendet werden.

2
wolfram77

Dies kann mithilfe der Numpy-Bibliothek erfolgen. Die arange () - Funktion erlaubt Schritte im Float. Es gibt jedoch ein numpy-Array zurück, das mit tolist () in unsere Liste umgewandelt werden kann.

for i in np.arange(0, 1, 0.1).tolist():
   print i
2
user3654478

Um den Problemen mit der Genauigkeit von Floaten entgegenzuwirken, können Sie das Modul Decimal verwenden.

Dies erfordert einen zusätzlichen Aufwand für die Konvertierung in Decimal von int oder float, während der Code geschrieben wird. Sie können jedoch stattdessen str übergeben und die Funktion ändern, wenn dies in der Tat erforderlich ist.

from decimal import Decimal
from decimal import Decimal as D


def decimal_range(*args):

    zero, one = Decimal('0'), Decimal('1')

    if len(args) == 1:
        start, stop, step = zero, args[0], one
    Elif len(args) == 2:
        start, stop, step = args + (one,)
    Elif len(args) == 3:
        start, stop, step = args
    else:
        raise ValueError('Expected 1 or 2 arguments, got %s' % len(args))

    if not all([type(arg) == Decimal for arg in (start, stop, step)]):
        raise ValueError('Arguments must be passed as <type: Decimal>')

    # neglect bad cases
    if (start == stop) or (start > stop and step >= zero) or \
                          (start < stop and step <= zero):
        return []

    current = start
    while abs(current) < abs(stop):
        yield current
        current += step

Beispielausgaben -

list(decimal_range(D('2')))
# [Decimal('0'), Decimal('1')]
list(decimal_range(D('2'), D('4.5')))
# [Decimal('2'), Decimal('3'), Decimal('4')]
list(decimal_range(D('2'), D('4.5'), D('0.5')))
# [Decimal('2'), Decimal('2.5'), Decimal('3.0'), Decimal('3.5'), Decimal('4.0')]
list(decimal_range(D('2'), D('4.5'), D('-0.5')))
# []
list(decimal_range(D('2'), D('-4.5'), D('-0.5')))
# [Decimal('2'),
#  Decimal('1.5'),
#  Decimal('1.0'),
#  Decimal('0.5'),
#  Decimal('0.0'),
#  Decimal('-0.5'),
#  Decimal('-1.0'),
#  Decimal('-1.5'),
#  Decimal('-2.0'),
#  Decimal('-2.5'),
#  Decimal('-3.0'),
#  Decimal('-3.5'),
#  Decimal('-4.0')]
1
shad0w_wa1k3r

Fügen Sie eine Autokorrektur hinzu, um die Möglichkeit einer fehlerhaften Anmeldung zu bestätigen:

def frange(start,step,stop):
    step *= 2*((stop>start)^(step<0))-1
    return [start+i*step for i in range(int((stop-start)/step))]
1
BobH

Überrascht hat noch niemand die empfohlene Lösung in den Python 3-Dokumenten erwähnt:

Siehe auch:

  • Das linspace-Rezept zeigt, wie eine Lazy-Version des Bereichs implementiert wird, die für Fließkommaanwendungen geeignet ist.

Einmal definiert, ist das Rezept einfach zu verwenden und erfordert keine numpy oder andere externe Bibliotheken, sondern Funktionen wie numpy.linspace(). Beachten Sie, dass anstelle des step-Arguments das dritte num-Argument die Anzahl der gewünschten Werte angibt, zum Beispiel:

print(linspace(0, 10, 5))
# linspace(0, 10, 5)
print(list(linspace(0, 10, 5)))
# [0.0, 2.5, 5.0, 7.5, 10]

Ich zitiere unten eine modifizierte Version des vollständigen Python 3-Rezepts von Andrew Barnert:

import collections.abc
import numbers

class linspace(collections.abc.Sequence):
    """linspace(start, stop, num) -> linspace object

    Return a virtual sequence of num numbers from start to stop (inclusive).

    If you need a half-open range, use linspace(start, stop, num+1)[:-1].
    """
    def __init__(self, start, stop, num):
        if not isinstance(num, numbers.Integral) or num <= 1:
            raise ValueError('num must be an integer > 1')
        self.start, self.stop, self.num = start, stop, num
        self.step = (stop-start)/(num-1)
    def __len__(self):
        return self.num
    def __getitem__(self, i):
        if isinstance(i, slice):
            return [self[x] for x in range(*i.indices(len(self)))]
        if i < 0:
            i = self.num + i
        if i >= self.num:
            raise IndexError('linspace object index out of range')
        if i == self.num-1:
            return self.stop
        return self.start + i*self.step
    def __repr__(self):
        return '{}({}, {}, {})'.format(type(self).__name__,
                                       self.start, self.stop, self.num)
    def __eq__(self, other):
        if not isinstance(other, linspace):
            return False
        return ((self.start, self.stop, self.num) ==
                (other.start, other.stop, other.num))
    def __ne__(self, other):
        return not self==other
    def __hash__(self):
        return hash((type(self), self.start, self.stop, self.num))
1
Chris_Rands

Beste Lösung: kein Rundungsfehler
_______________________________________________________________________________

>>> step = .1
>>> N = 10     # number of data points
>>> [ x / pow(step, -1) for x in range(0, N + 1) ]

[0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0]

_______________________________________________________________________________

Oder verwenden Sie für einen festgelegten Bereich anstelle festgelegter Datenpunkte (z. B. kontinuierliche Funktion) Folgendes:

>>> step = .1
>>> rnge = 1     # NOTE range = 1, i.e. span of data points
>>> N = int(rnge / step
>>> [ x / pow(step,-1) for x in range(0, N + 1) ]

[0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0]

Um eine Funktion zu implementieren, ersetzen Sie x / pow(step, -1) durch f( x / pow(step, -1) ) und definieren Sie f.
Zum Beispiel:

>>> import math
>>> def f(x):
        return math.sin(x)

>>> step = .1
>>> rnge = 1     # NOTE range = 1, i.e. span of data points
>>> N = int(rnge / step)
>>> [ f( x / pow(step,-1) ) for x in range(0, N + 1) ]

[0.0, 0.09983341664682815, 0.19866933079506122, 0.29552020666133955, 0.3894183423086505, 
 0.479425538604203, 0.5646424733950354, 0.644217687237691, 0.7173560908995228,
 0.7833269096274834, 0.8414709848078965]
1
Jason

Meine Lösung:

def seq(start, stop, step=1, digit=0):
    x = float(start)
    v = []
    while x <= stop:
        v.append(round(x,digit))
        x += step
    return v
1
Jjen

start und stop sind inklusiv und nicht in der ein oder anderen Art (normalerweise stop ist ausgeschlossen) und ohne Import und Verwendung von Generatoren

def rangef(start, stop, step, fround=5):
    """
    Yields sequence of numbers from start (inclusive) to stop (inclusive)
    by step (increment) with rounding set to n digits.

    :param start: start of sequence
    :param stop: end of sequence
    :param step: int or float increment (e.g. 1 or 0.001)
    :param fround: float rounding, n decimal places
    :return:
    """
    try:
        i = 0
        while stop >= start and step > 0:
            if i==0:
                yield start
            Elif start >= stop:
                yield stop
            Elif start < stop:
                if start == 0:
                    yield 0
                if start != 0:
                    yield start
            i += 1
            start += step
            start = round(start, fround)
        else:
            pass
    except TypeError as e:
        yield "type-error({})".format(e)
    else:
        pass


# passing
print(list(rangef(-100.0,10.0,1)))
print(list(rangef(-100,0,0.5)))
print(list(rangef(-1,1,0.2)))
print(list(rangef(-1,1,0.1)))
print(list(rangef(-1,1,0.05)))
print(list(rangef(-1,1,0.02)))
print(list(rangef(-1,1,0.01)))
print(list(rangef(-1,1,0.005)))
# failing: type-error:
print(list(rangef("1","10","1")))
print(list(rangef(1,10,"1")))

Python 3.6.2 (v3.6.2: 5fd33b5, 8. Juli 2017, 04:57:36) [MSC V.1900 64 Bit (AMD64)]

1
Goran B.

Ich weiß, ich bin zu spät zur Party hier, aber hier ist eine triviale Generatorlösung, die in 3.6 funktioniert:

def floatRange(*args):
    start, step = 0, 1
    if len(args) == 1:
        stop = args[0]
    Elif len(args) == 2:
        start, stop = args[0], args[1]
    Elif len(args) == 3:
        start, stop, step = args[0], args[1], args[2]
    else:
        raise TypeError("floatRange accepts 1, 2, or 3 arguments. ({0} given)".format(len(args)))
    for num in start, step, stop:
        if not isinstance(num, (int, float)):
            raise TypeError("floatRange only accepts float and integer arguments. ({0} : {1} given)".format(type(num), str(num)))
    for x in range(int((stop-start)/step)):
        yield start + (x * step)
    return

dann können Sie es genauso wie das Original range()... nennen. Es gibt keine Fehlerbehandlung, aber lassen Sie mich wissen, wenn ein Fehler vorliegt, der vernünftigerweise aufgefangen werden kann. oder Sie können es aktualisieren. Dies ist StackOverflow.

0
David Culbreth

Ich bin nur ein Anfänger, hatte aber bei der Simulation einiger Berechnungen das gleiche Problem. Hier habe ich versucht, das herauszufinden, was mit Dezimalschritten zu arbeiten scheint.

Ich bin auch ziemlich faul und so fiel es mir schwer, meine eigene Range-Funktion zu schreiben.

Grundsätzlich habe ich meine xrange(0.0, 1.0, 0.01) in xrange(0, 100, 1) geändert und die Division durch 100.0 innerhalb der Schleife verwendet. Ich war auch besorgt, ob es Rundungsfehler geben wird. Also entschied ich mich zu testen, ob es welche gibt. Nun habe ich gehört, dass, wenn 0.01 aus einer Berechnung nicht genau der Float 0.01 ist, der Vergleich sie False zurückgeben sollte (wenn ich falsch liege, lass es mich wissen).

Also habe ich beschlossen, zu testen, ob meine Lösung für mein Sortiment funktioniert, indem ich einen kurzen Test durchführe:

for d100 in xrange(0, 100, 1):
    d = d100 / 100.0
    fl = float("0.00"[:4 - len(str(d100))] + str(d100))
    print d, "=", fl , d == fl

Und es wurde für jeden gedruckt.

Wenn ich es völlig falsch finde, lass es mich wissen.

0
user2836437

frange (Start, Stopp, Präzision)

def frange(a,b,i):
    p = 10**i
    sr = a*p
    er = (b*p) + 1
    p = float(p)
    return map(lambda x: x/p, xrange(sr,er))

In >frange(-1,1,1)

Out>[-1.0, -0.9, -0.8, -0.7, -0.6, -0.5, -0.4, -0.3, -0.2, -0.1, 0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0]
0
zred

Viele der Lösungen hier hatten immer noch Gleitkomma-Fehler in Python 3.6 und taten nicht genau das, was ich persönlich brauchte. 

Die folgende Funktion nimmt Ganzzahlen oder Gleitkommazahlen, erfordert keine Importe und gibt keine Gleitkommafehler zurück.

def frange(x, y, step):
    if int(x + y + step) == (x + y + step):
        r = list(range(int(x), int(y), int(step)))
    else:
        f = 10 ** (len(str(step)) - str(step).find('.') - 1)
        rf = list(range(int(x * f), int(y * f), int(step * f)))
        r = [i / f for i in rf]

    return r
0
kowpow
sign = lambda x: (1, -1)[x < 0]
def frange(start, stop, step):
    i = 0
    r=len(str(step).split('.')[-1])
    args=(start,stop,step)
    if not step :return []
    if all(int(i)==float(i) for i in args):
        start,stop,step=map(int,args)
    if sign(step)==1:
        while start + i * step < stop:
            yield round(start + i * step,r)
            i += 1
    else:
        while start + i * step > stop:
            yield round(start + i * step,r)
            i += 1
0
SmartManoj

Hier ist meine Lösung, die mit float_range (-1, 0, 0.01) funktioniert und ohne Fließkomma-Darstellungsfehler funktioniert. Es ist nicht sehr schnell, funktioniert aber gut: 

from decimal import Decimal

def get_multiplier(_from, _to, step):
    digits = []
    for number in [_from, _to, step]:
        pre = Decimal(str(number)) % 1
        digit = len(str(pre)) - 2
        digits.append(digit)
    max_digits = max(digits)
    return float(10 ** (max_digits))


def float_range(_from, _to, step, include=False):
    """Generates a range list of floating point values over the Range [start, stop]
       with step size step
       include=True - allows to include right value to if possible
       !! Works fine with floating point representation !!
    """
    mult = get_multiplier(_from, _to, step)
    # print mult
    int_from = int(round(_from * mult))
    int_to = int(round(_to * mult))
    int_step = int(round(step * mult))
    # print int_from,int_to,int_step
    if include:
        result = range(int_from, int_to + int_step, int_step)
        result = [r for r in result if r <= int_to]
    else:
        result = range(int_from, int_to, int_step)
    # print result
    float_result = [r / mult for r in result]
    return float_result


print float_range(-1, 0, 0.01,include=False)

assert float_range(1.01, 2.06, 5.05 % 1, True) ==\
[1.01, 1.06, 1.11, 1.16, 1.21, 1.26, 1.31, 1.36, 1.41, 1.46, 1.51, 1.56, 1.61, 1.66, 1.71, 1.76, 1.81, 1.86, 1.91, 1.96, 2.01, 2.06]

assert float_range(1.01, 2.06, 5.05 % 1, False)==\
[1.01, 1.06, 1.11, 1.16, 1.21, 1.26, 1.31, 1.36, 1.41, 1.46, 1.51, 1.56, 1.61, 1.66, 1.71, 1.76, 1.81, 1.86, 1.91, 1.96, 2.01]
0
pymen

Dieser eine Liner wird Ihren Code nicht durcheinander bringen. Das Vorzeichen des Parameters step ist wichtig.

def frange(start, stop, step):
    return [x*step+start for x in range(0,round(abs((stop-start)/step)+0.5001),
        int((stop-start)/step<0)*-2+1)]
0
Tjaart