1. Warum brauchen wir einen Generator?
Durch das obige Lernen können wir die Formel zur Listengenerierung kennen und direkt eine Liste erstellen. Aufgrund von Speicherbeschränkungen ist die Listenkapazität jedoch definitiv begrenzt. Darüber hinaus nimmt die Erstellung einer Liste mit 10 Millionen Elementen nicht nur viel Speicherplatz in Anspruch, sondern wenn wir nur auf die ersten paar Elemente zugreifen müssen, wird der von den meisten nachfolgenden Elementen belegte Platz verschwendet.
Wenn also die Listenelemente nach einem bestimmten Algorithmus berechnet werden können, können wir dann während der Schleife kontinuierlich nachfolgende Elemente berechnen? Dies spart viel Platz, da keine vollständige Liste erstellt werden muss. In Python wird dieser Mechanismus der gleichzeitigen Schleife und Berechnung als Generator bezeichnet: Generator.
In Python werden Funktionen, die yield verwenden, als Generatoren bezeichnet.
Im Gegensatz zu gewöhnlichen Funktionen ist ein Generator eine Funktion, die einen Iterator zurückgibt und nur für iterative Operationen verwendet werden kann. Es ist einfacher zu verstehen, dass ein Generator ein Iterator ist.
Während des Aufrufs des Generators pausiert die Funktion jedes Mal, wenn sie auf Yield trifft, und speichert alle aktuellen Betriebsinformationen und gibt den Wert von Yield zurück. Und bei der nächsten Ausführung der next()-Methode von der aktuellen Position aus weiterlaufen.
Wie erstellt man also einen Generator?
2. Erstellen eines Generators
Der einfachste und einfachste Weg ist, das [] einer Listengenerierung in () zu ändern
# -*- coding: UTF-8 -*- gen= (x * x for x in range(10)) print(gen)
Ergebnis ausgeben :
<generator object <genexpr> at 0x0000000002734A40>
Der Unterschied zwischen dem Erstellen einer Liste und einem Generator besteht nur im äußersten [] und (). Aber der Generator erstellt nicht wirklich eine Liste von Zahlen, sondern gibt stattdessen einen Generator zurück, der bei jeder Berechnung ein Element „ergibt“ (ergibt). Der Generatorausdruck verwendet „verzögerte Bewertung“ (verzögerte Bewertung, auch übersetzt als „verzögerte Bewertung“, ich denke, diese Methode zum Aufrufen nach Bedarf lässt sich besser als „verzögert“ übersetzen) und wird nur beim Abrufen (Auswerten) zugewiesen, sodass mehr Speicher benötigt wird effizient, wenn die Liste lang ist.
Ich weiß also, wie man einen Generator erstellt, aber wie kann ich die darin enthaltenen Elemente anzeigen?
3. Durchlaufen Sie die Elemente des Generators
Nach unserer Überlegung können wir zum Durchlaufen Folgendes versuchen:
# -*- coding: UTF-8 -*- gen= (x * x for x in range(10)) for num in gen : print(num)
Richtig, Sie können es direkt so durchqueren. Natürlich wurden oben auch Iteratoren erwähnt. Kann next() also zum Durchlaufen verwendet werden? Natürlich ist es möglich.
4. Implementieren Sie den Generator in Form einer Funktion
Wie oben erwähnt, besteht der einfachste und einfachste Weg, einen Generator zu erstellen, darin, eine Liste [] zu erstellen Zu (). Warum wird es plötzlich in Form einer Funktion erstellt?
Tatsächlich ist ein Generator auch ein Iterator, aber Sie können ihn nur einmal iterieren. Dies liegt daran, dass sie nicht alle Werte im Speicher speichern, sondern die Werte zur Laufzeit generieren. Sie verwenden sie, indem Sie sie iterieren, indem Sie entweder eine „for“-Schleife verwenden oder sie an alle Funktionen und Strukturen übergeben, die iteriert werden können. Und in der tatsächlichen Anwendung werden die meisten Generatoren durch Funktionen implementiert. Wie erstellen wir es also durch Funktionen?
Keine Sorge, schauen wir uns dieses Beispiel an:
# -*- coding: UTF-8 -*- def my_function(): for i in range(10): print ( i ) my_function()
Ausgabeergebnis:
0 1 2 3 4 5 6 7 8 9
Wenn wir daraus einen Generator machen müssen, müssen wir nur print ändern ( i ) für Ertrag i Schauen wir uns das modifizierte Beispiel an:
# -*- coding: UTF-8 -*- def my_function(): for i in range(10): yield i print(my_function())
Ausgabeergebnis:
<generator object my_function at 0x0000000002534A40>
Dieses Beispiel ist jedoch für die Verwendung eines Generators sehr ungeeignet und kann die Eigenschaften des Generators nicht ausnutzen Der beste Anwendungsfall für Prozessoren ist, wenn Sie nicht für alle Berechnungen gleichzeitig eine große Ergebnismenge im Speicher reservieren möchten, insbesondere wenn die Ergebnismenge eine Schleife enthält. Denn das wird viele Ressourcen verbrauchen.
Das Folgende ist zum Beispiel ein Generator, der die Fibonacci-Folge berechnet:
# -*- coding: UTF-8 -*- def fibon(n): a = b = 1 for i in range(n): yield a a, b = b, a + b # 引用函数 for x in fibon(1000000): print(x , end = ' ')
Der Effekt des Ausführens:
Sehen Sie, wenn Sie einen Parameter wie diesen ausführen, It Man kann nicht sagen, dass es einen steckengebliebenen Zustand gibt, da diese Methode nicht zu viele Ressourcen verbraucht. Hier ist es am schwierigsten zu verstehen, dass der Ausführungsfluss von Generatoren und Funktionen unterschiedlich ist. Funktionen werden nacheinander ausgeführt und kehren zurück, wenn sie auf eine Return-Anweisung oder die letzte Zeile von Funktionsanweisungen stoßen. Die Funktion, die zum Generator wird, wird bei jedem Aufruf von next() ausgeführt, kehrt zurück, wenn eine Yield-Anweisung auftritt, und setzt die Ausführung bei der letzten zurückgegebenen Yield-Anweisung fort, wenn sie erneut ausgeführt wird.
Zum Beispiel dieses Beispiel:
# -*- coding: UTF-8 -*- def odd(): print ( 'step 1' ) yield ( 1 ) print ( 'step 2' ) yield ( 3 ) print ( 'step 3' ) yield ( 5 ) o = odd() print( next( o ) ) print( next( o ) ) print( next( o ) ) 输出的结果: step 1 1 step 2 3 step 3 5
Wie Sie sehen können, ist odd keine gewöhnliche Funktion, sondern ein Generator. Während der Ausführung wird sie unterbrochen, wenn eine Ausbeute auftritt, und die Ausführung wird unterbrochen weitermachen beim nächsten Mal. Nach dreimaliger Ausführung von yield gibt es keine weitere auszuführende Ausgabe. Wenn Sie mit print(next(o)) fortfahren, wird ein Fehler gemeldet. Daher werden Fehler normalerweise in der Generatorfunktion erfasst.
5. Yang-Hui-Dreieck drucken
Durch das Erlernen des Generators können wir die Wissenspunkte des Generators direkt zum Drucken des Yang-Hui-Dreiecks verwenden:
# -*- coding: UTF-8 -*- def triangles( n ): # 杨辉三角形 L = [1] while True: yield L L.append(0) L = [ L [ i -1 ] + L [ i ] for i in range (len(L))] n= 0 for t in triangles( 10 ): # 直接修改函数名即可运行 print(t) n = n + 1 if n == 10: break
Das Ausgabeergebnis ist:
[1] [1, 1] [1, 2, 1] [1, 3, 3, 1] [1, 4, 6, 4, 1] [1, 5, 10, 10, 5, 1] [1, 6, 15, 20, 15, 6, 1] [1, 7, 21, 35, 35, 21, 7, 1] [1, 8, 28, 56, 70, 56, 28, 8, 1] [1, 9, 36, 84, 126, 126, 84, 36, 9, 1]nächsten Abschnitt