1021 Stimmen

Wie verwendet man einen dezimalen Bereich()-Schrittwert?

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

Ich dachte, ich könnte es wie folgt machen, aber es hat nicht geklappt:

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.

5voto

Nisan.H Punkte 5694

Meine Versionen verwenden die ursprüngliche Bereichsfunktion zur Erstellung multiplikativer Indizes für die Verschiebung. Dies ermöglicht die gleiche Syntax wie bei der ursprünglichen Bereichsfunktion. Ich habe zwei Versionen erstellt, eine mit Float und eine mit Decimal, weil ich in einigen Fällen die Rundungsdrift vermeiden wollte, die durch die Fließkommaarithmetik entsteht.

Es ist konsistent mit leeren Mengenergebnissen wie bei range/xrange.

Wenn Sie nur einen einzigen numerischen Wert an eine der beiden Funktionen übergeben, wird der Standardbereich bis zum ganzzahligen Höchstwert des Eingabeparameters zurückgegeben (wenn Sie also 5,5 eingeben, würde der Bereich(6) zurückgegeben).

Edit: der untenstehende 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)) # []

5voto

kowpow Punkte 75

Viele der Lösungen hier hatten noch Fließkommafehler in Python 3.6 und taten nicht genau das, was ich persönlich brauchte.

Die nachstehende Funktion nimmt Ganzzahlen oder Fließkommazahlen an, erfordert keine Importe und gibt keine Fließkommafehler 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

3voto

Carlos Vega Punkte 1301

Dies ist meine Lösung, um Bereiche mit Float-Schritten zu erhalten.
Mit dieser Funktion ist es nicht notwendig, numpy zu importieren oder zu installieren.
Ich bin mir ziemlich sicher, dass sie verbessert und optimiert werden kann. Fühlen Sie sich frei, dies zu tun und posten Sie es hier.

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]

3voto

Bijou Trouvaille Punkte 7666

Der Vollständigkeit halber: 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)

2voto

user3654478 Punkte 67

Dies kann mit der Numpy-Bibliothek erfolgen. Die Funktion arange() erlaubt Schritte in Float. Sie gibt jedoch ein Numpy-Array zurück, das zu unserer Bequemlichkeit mit tolist() in eine Liste umgewandelt werden kann.

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

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X