12901 Stimmen

Was bewirkt das Schlüsselwort "yield"?

Wozu dient die yield Schlüsselwort in Python? Was bewirkt es?

Ich versuche zum Beispiel, folgenden Code zu verstehen 1 :

def _get_child_candidates(self, distance, min_dist, max_dist):
    if self._leftchild and distance - max_dist < self._median:
        yield self._leftchild
    if self._rightchild and distance + max_dist >= self._median:
        yield self._rightchild  

Und das ist der Anrufer:

result, candidates = [], [self]
while candidates:
    node = candidates.pop()
    distance = node._get_dist(obj)
    if distance <= max_dist and distance >= min_dist:
        result.extend(node._values)
    candidates.extend(node._get_child_candidates(distance, min_dist, max_dist))
return result

Was passiert, wenn die Methode _get_child_candidates aufgerufen wird? Wird eine Liste zurückgegeben? Ein einzelnes Element? Wird sie erneut aufgerufen? Wann werden die nachfolgenden Aufrufe beendet?


1. Dieses Stück Code wurde von Jochen Schulz (jrschulz) geschrieben, der eine großartige Python-Bibliothek für metrische Räume entwickelt hat. Dies ist der Link zum vollständigen Quellcode: <a href="https://well-adjusted.de/~jrspieker/mspace/" rel="noreferrer">Modul mspace </a>.

0voto

Conjure.Li Punkte 20

Um seine Ertragsfunktion zu verstehen, muss man wissen, was ein Generator ist. Bevor man Generatoren versteht, muss man außerdem verstehen Iterables . Iterabel: iterabel Um eine Liste zu erstellen, müssen Sie natürlich in der Lage sein, jedes Element einzeln zu lesen. Der Prozess, bei dem die Elemente eines nach dem anderen gelesen werden, wird Iteration genannt:

>>> mylist = [1, 2, 3]
>>> for i in mylist:
...    print(i)
1
2
3 

mylist ist eine Iterable. Wenn Sie List Comprehensions verwenden, erstellen Sie eine Liste und damit eine Iterable

>>> mylist = [x*x for x in range(3)]
>>> for i in mylist:
...    print(i)
0
1
4 

Alle Datenstrukturen, die für... in... verwendet werden können, sind iterierbar; Listen, Strings, Dateien...

Diese iterierbaren Methoden sind praktisch, weil man sie nach Belieben lesen kann, aber man speichert alle Werte im Speicher, was bei vielen Werten nicht immer wünschenswert ist. Generator: Generator Ein Generator ist ebenfalls eine Art Iterator, eine spezielle Art der Iteration, die nur einmal durchlaufen werden kann. Der Generator speichert nicht alle Werte im Speicher, sondern generiert Werte im laufenden Betrieb:

Generator: Generator, Generator, Generator erzeugt Strom, speichert aber keine Energie;)

>>> mygenerator = (x*x for x in range(3))
>>> for i in mygenerator:
...    print(i)
0
1
4 

Solange () anstelle von [] verwendet wird, wird das Listenverständnis zum Generatorverständnis. Da der Generator jedoch nur einmal verwendet werden kann, können Sie for i in mygenerator nicht ein zweites Mal ausführen: Der Generator berechnet 0, verwirft es dann, berechnet dann 1, und beim letzten Mal berechnet er 4. Der typische schwarze Blinde Mann bricht den Mais.

Das Schlüsselwort yield wird auf die gleiche Weise wie return verwendet, mit dem Unterschied, dass die Funktion den Generator zurückgibt.

>>> def createGenerator():
...    mylist = range(3)
...    for i in mylist:
...        yield i*i
...
>>> mygenerator = createGenerator() 
>>> print(mygenerator) 
<generator object createGenerator at 0xb7555c34>
>>> for i in mygenerator:
...     print(i)
0
1
4 

Dieses Beispiel ist an sich nutzlos, aber wenn Sie eine Funktion benötigen, die eine große Anzahl von Werten zurückgibt und diese nur einmal lesen müssen, ist die Verwendung von yield sehr praktisch.

Um die Ausbeute zu beherrschen, muss man sich darüber im Klaren sein, dass beim Aufruf einer Funktion der im Funktionskörper geschriebene Code nicht ausgeführt wird. Die Funktion gibt nur das Generatorobjekt zurück. Anfänger sind in dieser Hinsicht wahrscheinlich verwirrt.

Zweitens müssen Sie sich darüber im Klaren sein, dass der Code jedes Mal, wenn Sie den Generator verwenden, dort weiterläuft, wo er aufgehört hat.

Der schwierigste Teil ist jetzt:

Wenn for zum ersten Mal das Generatorobjekt aufruft, das aus Ihrer Funktion erstellt wurde, wird der Code in der Funktion von Anfang an ausgeführt, bis er auf yield trifft, und dann wird der erste Wert der Schleife zurückgegeben. Danach wird bei jedem weiteren Aufruf die nächste Iteration der von Ihnen in der Funktion geschriebenen Schleife ausgeführt und der nächste Wert zurückgegeben. Dies wird so lange fortgesetzt, bis der Generator als leer angesehen wird, was dann der Fall ist, wenn es keinen Treffer gibt, während die Funktion ausgeführt wird. Das kann daran liegen, dass die Schleife beendet ist, oder daran, dass Sie mit "if/else" nicht mehr zufrieden sind.

Persönliches Verständnis Ich hoffe, dass ich Ihnen helfen kann!

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