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.

2voto

Goran B. Punkte 534

Start und stop sind inbegriffen und nicht eines oder das andere (normalerweise ist stop ausgeschlossen) und ohne Importe und unter 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, Jul 8 2017, 04:57:36) [MSC v.1900 64 bit (AMD64)]

2voto

shad0w_wa1k3r Punkte 12149

Um den Problemen mit der Float-Präzision zu begegnen, können Sie die Decimal Modul .

Dies erfordert einen zusätzlichen Aufwand für die Umwandlung in Decimal von int o float beim Schreiben des Codes, aber Sie können stattdessen str und ändern Sie die Funktion, wenn diese Art von Bequemlichkeit tatsächlich erforderlich ist.

from decimal import Decimal

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

Beispielhafte Ausgaben -

from decimal import Decimal as D

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')]

2voto

David Culbreth Punkte 2307

Ich weiß, ich bin spät zu der Partei hier, aber hier ist eine triviale Generator-Lö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 genau wie das Original aufrufen range() ... es gibt keine Fehlerbehandlung, aber lassen Sie mich wissen, wenn es einen Fehler gibt, der vernünftig gefangen werden kann, und ich werde aktualisieren. oder Sie können es aktualisieren.

2voto

user376536 Punkte 21

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)))

1voto

wolfram77 Punkte 2301

Der Trick zur Vermeidung Abrundungsproblem ist die Verwendung einer separaten Nummer, um den Bereich zu durchlaufen, der beginnt und halb el 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 dazu, numpy.arange verwendet werden können.

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