Vorsichtsmaßnahmen beim Erstellen eines Python-Generators

Am Ende des folgenden Artikels schrieb ich, dass der Generator containerisiert werden sollte.

Diesmal werde ich das erklären.

Erstellen Sie zunächst einen Generator, der die Fibonacci-Zahl wie zuvor generiert. In den Kommentaren des vorherigen Artikels wurde mir eine ausgefeilte Schreibweise beigebracht, daher werde ich diese verwenden.

Python


#Generator
def fibonacci_generator():
    a, b = 0, 1
    while True:
        yield a
        a, b = b, a + b

#Containergenerator
class FibonacciGenerator(object):
    def __iter__(self):
        a, b = 0, 1
        while True:
            yield a
            a, b = b, a + b

Diese geben das gleiche Ergebnis aus.

Python


for fib in fibonacci_generator():
    if fib > 1000:
        break
    print fib,

print

for fib in FibonacciGenerator():
    if fib > 1000:
        break
    print fib,

Ergebnis


 0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987
 0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987

Beachten Sie, dass sich die beiden obigen for-Anweisungen nur im Generator unterscheiden. Es ist mühsam, diesen Code jedes Mal zu schreiben, wenn der Generator wechselt. Machen wir ihn also zu einer Funktion.

Python


def print_fib(fib_iterator, limit = 1000):
    for fib in fib_iterator:
        if fib > limit:
            break
        print fib,
    print

print_fib(fibonacci_generator())
print_fib(FibonacciGenerator())

Ergebnis


 0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987
 0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987

Es war ordentlich, eine Funktion zum Empfangen des Generators zu erstellen.

Ändern wir nun diese Funktion, um den Inhalt des Generators zweimal anzuzeigen.

Python


def print_fib_twice(fib_iterator, limit = 100):
    print "[1]",
    for fib in fib_iterator:
        if fib > limit:
            break
        print fib,
    print " [2]",
    for fib in fib_iterator:
        if fib > limit:
            break
        print fib,
    print

print_fib_twice(fibonacci_generator())
print_fib_twice(FibonacciGenerator())

Ergebnis


[1] 0 1 1 2 3 5 8 13 21 34 55 89  [2]
[1] 0 1 1 2 3 5 8 13 21 34 55 89  [2] 0 1 1 2 3 5 8 13 21 34 55 89

Der Generator, der nicht containerisiert ist, zeigt den Inhalt des zweiten Mal nicht an. Der Grund dafür ist, dass, wenn Sie den Generator so wie er ist verwenden, derselbe beim ersten und beim zweiten Mal wiederverwendet wird. Der containerisierte Generator erstellt für jede Schleife einen neuen Generator. Dies ist leicht zu verstehen, wenn Sie Folgendes versuchen.

Python


def print_fib_twice2(fib_iterator, limit1, limit2):
    print "[1]",
    for fib in fib_iterator:
        if fib > limit1:
            break
        print fib,
    print " [2]",
    for fib in fib_iterator:
        if fib > limit2:
            break
        print fib,
    print

print_fib_twice2(fibonacci_generator(), limit1 = 100, limit2 = 400)
print_fib_twice2(FibonacciGenerator(),  limit1 = 100, limit2 = 400)

Ergebnis


[1] 0 1 1 2 3 5 8 13 21 34 55 89  [2] 233 377
[1] 0 1 1 2 3 5 8 13 21 34 55 89  [2] 0 1 1 2 3 5 8 13 21 34 55 89 144 233 377

Auf diese Weise verursacht der Generator einen unerwarteten Fehler, wenn er an eine Funktion übergeben wird, die intern mehrfach verwendet wird. Daher ist es im Allgemeinen sicherer, daraus einen Behälter zu machen.

Im Gegenteil, wenn Sie eine Funktion schreiben, die einen Iterator empfängt, ist es besser zu überprüfen, ob sie containerisiert ist. Sie können feststellen, ob ein Iterator containerisiert ist, indem Sie iter () zweimal anwenden und prüfen, ob verschiedene Iteratoren zurückgegeben werden.

Python


def print_fib_twice3(fib_iterator, limit = 100):
    if iter(fib_iterator) is iter(fib_iterator):
        raise TypeError("Must supply a container")

    print "[1]",
    for fib in fib_iterator:
        if fib > limit:
            break
        print fib,
    print " [2]",
    for fib in fib_iterator:
        if fib > limit:
            break
        print fib,
    print

Python


print_fib_twice3(fibonacci_generator())

Ergebnis


TypeError: Must supply a container

Python


print_fib_twice3(FibonacciGenerator())

Ergebnis


[1] 0 1 1 2 3 5 8 13 21 34 55 89  [2] 0 1 1 2 3 5 8 13 21 34 55 89

Dies verhindert unbeabsichtigtes Verhalten.

Enjoy!

Recommended Posts

Vorsichtsmaßnahmen beim Erstellen eines Python-Generators
Vorsichtsmaßnahmen beim Beizen einer Funktion in Python
Probleme beim Erstellen eines CSV-JSON-Konvertierungstools mit Python
Ein Hinweis beim Erstellen eines gerichteten Diagramms mit Graphviz in Python
[Python] Memo zum Erstellen von Scraping-Tools
Vorsichtsmaßnahmen, die beim Aufbau einer PYTHON-Umgebung beachtet werden müssen
Beim Erstellen einer Matrix in einer Liste
Vorsichtsmaßnahmen bei der Verwendung von Phantomjs aus Python
Vorsichtsmaßnahmen bei Verwendung von sechs mit Python 2.5
[Python] Kapitel 03-01 Schildkrötengrafiken (Erstellen einer Schildkröte)
Beim Schreiben eines Programms in Python
Vorsichtsmaßnahmen beim Erstellen eines zweidimensionalen Arrays mit denselben Werten
Erstellen einer einfachen Power-Datei mit Python
[Python] Verwenden Sie und und oder beim Erstellen von Variablen
Hinweise beim Erstellen einer Umgebung mit Python
Zu beachtende Punkte bei der Lösung von DP-Problemen mit Python
Dinge, auf die Sie beim Erstellen einer Python-Umgebung auf einem Mac achten sollten
[Python] Generatorfunktion
[Python-Memo] Seien Sie vorsichtig, wenn Sie ein zweidimensionales Array erstellen (Liste der Listen).
Fehler beim Installieren eines Moduls mit Python pip
Python-Variablenargument Ein Memorandum beim Erben einer definierten Klasse
Vorgehensweise zum Erstellen eines mit Python erstellten LineBot
Vorsichtsmaßnahmen beim Umgang mit Kontrollstrukturen in Python 2.6
[Python] Vorsichtsmaßnahmen beim Zuweisen von Werten zu mehrdimensionalen Arrays
Python Hinweis: Wenn Sie einer Zeichenfolge einen Wert zuweisen
Befehle zum Erstellen einer Python3-Umgebung mit virtualenv
Verfahren zum Erstellen einer Python-Isolationsumgebung (venv-Umgebung)
Traps beim Ausführen von ausführbaren Python Windows-Dateien
Hinweise zum Erstellen einer Python-Umgebung durch Anfänger
[Webentwicklung mit Python] Vorsichtsmaßnahmen beim Speichern von Cookies
Die Geschichte, wenn ein Python-Benutzer eine JSON-Datei übergibt
Vorsichtsmaßnahmen beim Erstellen einer Ansicht, die Datensätze nach Datum und Uhrzeit eingrenzt
Ein * Algorithmus (Python Edition)
Ich möchte einen Python-Generator viele Male iterieren
[Python] Machen Sie einen Screenshot
Vorsichtsmaßnahmen beim Umgang mit Luigi
Versuchen Sie, eine komprimierte Datei mit Python und zlib zu erstellen
4. Erstellen eines strukturierten Programms
Pythons Lambda-Ausdruck ...
Memo zum Erstellen einer Python-Entwicklungsumgebung mit macOS Catalina
Ein Memorandum beim Schreiben von experimentellem Code ~ Anmelden in Python
Vorsichtsmaßnahmen bei der Installation eines hierarchischen Include-Verzeichnisses mit waf
Vorsichtsmaßnahmen beim Umgang mit ROS MultiArray in Python
Tipps und Vorsichtsmaßnahmen beim Portieren von MATLAB-Programmen nach Python
Dämonisiere einen Python-Prozess
Erstellung von Schabewerkzeugen
Beachten Sie beim Initialisieren einer Liste in Python
Was ist in dieser Variablen (wenn das Python-Skript ausgeführt wird)?
Implementieren eines Generators mit Python> Link> Yield und next ()> Yield
Verwenden Sie communic (), wenn Sie eine Ausgabe in einem Python-Unterprozess empfangen
Zundokokiyoshi (Generator) in Python
Vorsichtsmaßnahmen bei der Installation von fbprophet
Erstellen Sie eine Python-Umgebung
Erstellen eines Dataset Loader
Aktuelles Verzeichnis beim Erstellen eines neuen Verzeichnisses mit Jupyter