Python-Generatoren: Speichereffiziente Iteratoren

Erfahren Sie, wie Sie Python-Generatoren und Yield-Anweisungen verwenden, um große Datensätze mit minimalem Speicherbedarf zu verarbeiten. Master-Generator-Ausdrücke.

Versuchen Sie es im Editor

Übersicht

Beim Schreiben von Code, der Tausende oder Millionen Datensätze verarbeitet, ist die Speicherverwaltung von entscheidender Bedeutung. Wenn Sie einen gesamten Datensatz in eine Liste laden, besteht die Gefahr, dass Ihnen der Arbeitsspeicher ausgeht und der Server abstürzt. Python-Generatoren lösen dieses Problem, indem sie einen Mechanismus zum Streamen von Daten bei Bedarf bereitstellen. Anstatt den gesamten Datensatz auf einmal zu berechnen und im Speicher zu speichern, erzeugt ein Generator jeweils ein Element, übergibt es an den Aufrufer und hält seine Ausführung an, bis das nächste Element angefordert wird.

Generatoren werden wie normale Funktionen definiert, verwenden jedoch das Schlüsselwort „yield“ anstelle von „return“. Wenn eine Generatorfunktion aufgerufen wird, gibt sie ein Generator-Iteratorobjekt zurück, ohne die internen Anweisungen der Funktion auszuführen. Wenn der Aufrufer „next()“ auf dem Generator aufruft (oder ihn durchläuft), wird die Funktion ausgeführt, bis sie „yield“ erreicht. An diesem Punkt liefert der Generator den Wert, speichert seine lokalen Variablen und unterbricht die Ausführung. Bei einem erneuten Aufruf wird der Vorgang genau dort fortgesetzt, wo er aufgehört hat.

Sie können Generatoren auch mithilfe von Generatorausdrücken erstellen, die eine mit Listenverständnissen identische Syntax verwenden, jedoch in Klammern „(...)“ anstelle der Klammern „[...]“ eingeschlossen sind. Dadurch ist es unglaublich einfach, Listenverständnisse durch speichereffiziente Iteratoren zu ersetzen. Durch die Vermeidung massiver Speicherzuweisungen sind Generatoren unverzichtbar für die Arbeit mit großen Protokollen, das Streamen von Daten aus Datenbanken oder die Durchführung von Berechnungen für mathematische Sequenzen unendlicher Länge.

Code- und Ausführungsausgabe

Ein benutzerdefinierter Generator, der Fibonacci-Zahlen und einen speichereffizienten Generatorausdruck liefert.

generators_demo.py
Versuchen Sie es im Editor
def fibonacci_generator(limit):
    """Yields Fibonacci numbers up to the limit."""
    a, b = 0, 1
    count = 0
    while count < limit:
        yield a
        a, b = b, a + b
        count += 1

# Instantiate generator
fib = fibonacci_generator(5)
print("--- Using Generator Function ---")
for num in fib:
    print(num)

# Generator expression (squares of numbers)
squares_gen = (x**2 for x in range(1, 1000000))
print("\n--- Using Generator Expression ---")
print(next(squares_gen))
print(next(squares_gen))
print(next(squares_gen))
Terminal-Ausgabe
--- Using Generator Function ---
0
1
1
2
3

--- Using Generator Expression ---
1
4
9

Schrittweise Umsetzung

  • Zeilenweises Lesen von Dateien, die zu groß für den RAM sind
  • Generieren einer unendlichen Folge von IDs oder mathematischen Zahlen
  • Datenbankeinträge stapelweise streamen, um API-Aufrufe zu verarbeiten

Häufig gestellte Fragen

Was ist der Unterschied zwischen Rendite und Rendite?

return beendet die Funktion vollständig. yield gibt einen Wert zurück und pausiert die Funktion, wobei ihr Zustand gespeichert wird, sodass sie bei Anforderung fortgesetzt werden kann.

Was passiert, wenn einem Generator die Artikel ausgehen?

Es löst eine StopIteration-Ausnahme aus. In einer „for“-Schleife fängt Python diese Ausnahme automatisch ab, um die Schleife sauber zu beenden.

Verwandte Themen

Empfohlene Python-Ressourcen

Erweitern Sie Ihr Wissen mit zugehörigen interaktiven Tutorials, Spickzetteln und Codevergleichen.