[PYTHON] Verwendung des Generators

Generator

Einfach ausgedrückt fühlt sich die Generatorfunktion so an, als ob in der Mitte der Funktion ein "Return" erstellt werden kann. Die Funktion ist jedoch, dass sie nicht endet, selbst wenn Sie so etwas wie "Zurück" tun. Außerdem werde ich sie einzeln zurückgeben, sodass ich nicht viel Speicher verwende. Ich werde auch die in python3 hinzugefügten Subgeneratoren erklären. Diesmal erstellter Code: https://github.com/KodairaTomonori/Qiita/tree/master/default_module/syntax Verwenden Sie tatsächlich "Yield" anstelle von "Return". Zunächst einmal einfach aus den Funktionen "Zähler" und "Fibonatti", die zählen

Grundlegende Verwendung (Ausbeute,. \ _ \ _ Next__ (), .close ())

counter_and_fibonati.py


def counter():
    num = 0
    while True:
        yield num
        num += 1

def fibonatti():
    now = 0
    next_num = 1
    while True:
        yield now
        now, next_num = next_num, now + next_num

if __name__ == '__main__':
    count = counter()
    print('print 0-3, for i in count')
    for i in count:
        print(i, end=', ')
        if i >= 3:
            print()
            break
    print('next_count, count.__next__()')
    print(count.__next__())
    print('print 5-7, for i in count')
    for i in count:
        print(i, end=', ')
        if i >= 7:
            count.close()
            print()
    print('print fibonatti')
    for i in fibonatti():
       if i > 100: break
       print(i, end=', ')
    print(i)

Ausgabe

print 0-3, for i in count 0, 1, 2, 3, next_count, count.__next__() 4 print 5-7, for i in count 5, 6, 7, print fibonatti 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144

Kommentar

Erstens ist die Funktion "Zähler" einfach, beginnend mit "num = 0" und Eingabe der Endlosschleife "while". Gibt für jede Schleife num mit yield num zurück. Dann wurde "Zähler" genannt? Manchmal wird "num + 1" und dann "Yield num" zurückgegeben. Bei jedem Aufruf wird ein Wert "+ 1" zurückgegeben. Wenn Sie es verwenden, wird es anstelle von "main" geschrieben. Wenn Sie es jedoch in die "for" -Anweisung einfügen, wird der Wert "0,1,2,3" nacheinander für jede Schleife zurückgegeben.

Sie können den Status (num) speichern, indem Sie ihn als Variable mit count = counter () definieren.

Wenn Sie "count .__ next__ ()" verwenden, wird die nächste Zahl zurückgegeben, dh "4".

Die folgenden for-Anweisungen werden auf die gleiche Weise wie zuvor einzeln zurückgegeben. Im Gegensatz zu zuvor stoppt der Zustand von "count" jedoch bei "num = 4", sodass diese Schleife bei "5" beginnt. Dann, am Ende, als es "7" oder mehr wurde, habe ich "count.close ()" gezählt, um die Schleife zu beenden.

Wenn Sie ".close ()" verwenden, können Sie die "for" -Anweisung beenden und die Funktion als Generator von "count" verlieren. Spucken Sie danach count .__ next__ () und StopIteration aus.

Das Fibonatti ist fast das gleiche, daher gibt es kein besonderes Problem. In diesem Fall wird der Generator direkt mit "fibonatti ()" platziert. Nach dem Beenden der "for" -Anweisung wird der Generator, in dem "next_num" gespeichert ist, irgendwohin verschoben.

Die Tatsache, dass es mit einer "for" -Anweisung umgewandelt werden kann, kann in eine "list" umgewandelt werden, indem es in "list ()" eingeschlossen wird. Beachten Sie jedoch, dass Sie in einer Endlosschleife sterben, wenn Sie in der Generatorfunktion kein Limit festlegen.

Wenn Sie bei jedem Anruf ein Argument angeben möchten

Sie können jedes Mal ein Argument mit .send (x) übergeben. Da .send (x) x an der Position vonield ergibt, müssen Sie .__ next__ () `einmal ausführen.

generator_send.



def generator(step):
    val = 0
    prev = 0
    while True:
        if step == None:
            step = prev
        prev = step
        val += step
        step = yield val

if __name__ == '__main__':
    gen = generator(0)
    print(gen.__next__(), end=', ')
    for i in [1,2,3,4,5,6]:
        print(gen.send(i) , end=', ')
    print()

Ausgabe

0, 1, 3, 6, 10, 15, 21,

Kommentar

Die Funktion generator ist ein Programm, das das empfangene Argument step zu val hinzufügt. Setzen Sie zuerst den Anfangswert generator (0) auf 0. Verwenden Sie dann .__ next__ (), um zu step =ield val zu gelangen. Dann wird "0" zurückgegeben. Geben Sie dann die for-Anweisung ein und wechseln Sie von "1 zu 6". Wenn "gen.send (i)" ausgeführt wird, wird "i" im vorherigen "Schritt = Ertragswert" eingegeben. Mit anderen Worten, wenn Sie "gen.send (i)" ausführen, erhalten Sie "step = i". Ich werde so eine Schleife machen. Wenn Sie hier ".__ next __ ()" ausführen, ohne ".send ()" zu verwenden, erhalten Sie "step = None".

Neu in Python3: Subgenerator

Der Untergenerator führt den Generator aus, wenn Sie "vom Generator nachgeben". generator ist eine Generatorfunktion. Dies macht eine Wiederholung sehr bequem.

Ein Beispielprogramm zum Erzeugen einer Sequenz, die dieselbe enthält, ist unten gezeigt.

ex_permutation.py


def ex_permutation(iterable, now_list=[]):
    if not iterable: 
        yield now_list
        return
    for i in [iterable.index(i) for i in set(iterable) ]:
        yield from permutation(iterable[:i] + iterable[i+1:], now_list + [iterable[i] ])

if __name__ == '__main__':
    permu = ex_permutation([2,2,3])
    for i in permu:
        print(i)

Ausgabe

[2, 2, 3] [2, 3, 2] [3, 2, 2]

Kommentar

Es ist mir egal, was drin ist, aber ich mache es nur rekursiv mit set (), damit es nicht abgedeckt wird. Sie können also rekursiv mit "Ausbeute von" schreiben. Schließlich wird "now_list" zurückgegeben, wenn der Inhalt von "iterable" erschöpft ist. Ich weiß nicht was es ist, aber es ist praktisch! Ohne das scheint es verwirrend zu sein.

Zusammenfassung

Sie können einen Wert in der Mitte der Funktion mit ield zurückgeben. Sie können die Generatorfunktion mit .close () beenden. Führen Sie die folgenden Schritte mit .__ next__ () aus Sie können einen Wert mit .send () übergeben Ausbeute von ist praktisch.

Recommended Posts

Verwendung des Generators
Wie benutzt man den Dekorateur?
Verwendung der Zip-Funktion
Verwendung des optparse-Moduls
Verwendung des ConfigParser-Moduls
Verwendung von xml.etree.ElementTree
Wie benutzt man Python-Shell
Hinweise zur Verwendung von tf.data
Verwendung von virtualenv
Verwendung der Spark ML-Pipeline
Wie benutzt man Seaboan?
Verwendung von Image-Match
Verwendung von Pandas 2
Verwendung von Virtualenv
Verwendung von numpy.vectorize
Verwendung von pytest_report_header
[Linux] Verwendung des Befehls echo
Wie man teilweise verwendet
Wie man Bio.Phylo benutzt
Verwendung von SymPy
Wie man x-means benutzt
Verwendung von WikiExtractor.py
Verwendung von IPython
Verwendung von virtualenv
Wie benutzt man Matplotlib?
Verwendung von iptables
Wie benutzt man numpy?
Verwendung von TokyoTechFes2015
Wie benutzt man venv
Verwendung des Wörterbuchs {}
Wie benutzt man Pyenv?
Verwendung der Liste []
Wie man Python-Kabusapi benutzt
Verwendung von OptParse
Verwendung des IPython-Debuggers (ipdb)
Verwendung von return
Wie man Imutils benutzt
Verwendung der C-Bibliothek in Python
So verwenden Sie MkDocs zum ersten Mal
Verwendung der Grafikzeichnungsbibliothek Bokeh
Verwendung der Google Cloud Translation API
Verwendung der NHK-Programmführer-API
[Algorithmus x Python] Verwendung der Liste
Verwendung von Qt Designer
Verwendung der Suche sortiert
[gensim] Verwendung von Doc2Vec
python3: Verwendung der Flasche (2)
Verstehen Sie, wie man Django-Filter verwendet
[Python] Verwendung von Liste 1
Verwendung von FastAPI ③ OpenAPI
Wie benutzt man Python Argparse?
Verwendung von IPython Notebook
Wie man Pandas Rolling benutzt
[Hinweis] Verwendung von virtualenv
Verwendung von Redispy-Wörterbüchern
Python: Wie man pydub benutzt