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>.

7voto

Saurabh Dhage Punkte 1420

In einfachen Worten

Die Yield-Anweisung unterbricht die Ausführung der Funktion und sendet einen Wert an den Aufrufer zurück, behält aber einen ausreichenden Zustand bei, damit die Funktion an der Stelle fortgesetzt werden kann, an der sie unterbrochen wurde. Bei der Wiederaufnahme setzt die Funktion ihre Ausführung unmittelbar nach dem letzten Yield-Lauf fort. Dadurch kann der Code eine Reihe von Werten im Laufe der Zeit erzeugen, anstatt sie auf einmal zu berechnen und wie eine Liste zurückzusenden.

Sehen wir uns das an einem Beispiel an:

# A Simple Python program to demonstrate working
# of yield

# A generator function that yields 1 for the first time,
# 2 second time and 3 third time
def simpleGeneratorFun():
    yield 1
    yield 2
    yield 3

Treibercode zur Überprüfung der obigen Generatorfunktion

for value in simpleGeneratorFun(): 
    print(value)

Output:

1
2
3

Return sendet einen bestimmten Wert an seinen Aufrufer zurück, während Yield eine Folge von Werten erzeugen kann. Wir sollten Yield verwenden, wenn wir über eine Sequenz iterieren wollen, aber nicht die gesamte Sequenz im Speicher speichern wollen.

Ausbeute werden in Python-Generatoren verwendet. Eine Generatorfunktion wird wie eine normale Funktion definiert, aber immer dann, wenn sie einen Wert erzeugen muss, tut sie dies mit dem Schlüsselwort yield statt mit return. Wenn der Körper einer def das Schlüsselwort yield enthält, wird die Funktion automatisch zu einer Generatorfunktion.

5voto

Normalerweise wird es verwendet, um einen Iterator aus einer Funktion zu erstellen. Stellen Sie sich 'yield' als ein append() an Ihre Funktion und Ihre Funktion als ein Array vor. Und wenn bestimmte Kriterien erfüllt sind, können Sie diesen Wert in Ihre Funktion einfügen, um sie zu einem Iterator zu machen.

arr=[]
if 2>0:
   arr.append(2)

def func():
   if 2>0:
      yield 2

wird die Ausgabe für beide gleich sein.

Der Hauptvorteil der Verwendung von yield ist die Erstellung von Iteratoren. Iteratoren berechnen den Wert der einzelnen Elemente nicht, wenn sie instanziiert werden. Sie berechnen ihn erst, wenn Sie ihn abfragen. Dies wird als "lazy evaluation" bezeichnet.

5voto

michalmonday Punkte 317

Generatoren ermöglichen es, einzelne verarbeitete Elemente sofort zu erhalten (ohne auf die Verarbeitung der gesamten Sammlung warten zu müssen). Dies wird im folgenden Beispiel veranschaulicht.

import time

def get_gen():
    for i in range(10):
        yield i
        time.sleep(1)

def get_list():
    ret = []
    for i in range(10):
        ret.append(i)
        time.sleep(1)
    return ret

start_time = time.time()
print('get_gen iteration (individual results come immediately)')
for i in get_gen():
    print(f'result arrived after: {time.time() - start_time:.0f} seconds')
print()

start_time = time.time()
print('get_list iteration (results come all at once)') 
for i in get_list():
    print(f'result arrived after: {time.time() - start_time:.0f} seconds')

get_gen iteration (individual results come immediately)
result arrived after: 0 seconds
result arrived after: 1 seconds
result arrived after: 2 seconds
result arrived after: 3 seconds
result arrived after: 4 seconds
result arrived after: 5 seconds
result arrived after: 6 seconds
result arrived after: 7 seconds
result arrived after: 8 seconds
result arrived after: 9 seconds

get_list iteration (results come all at once)
result arrived after: 10 seconds
result arrived after: 10 seconds
result arrived after: 10 seconds
result arrived after: 10 seconds
result arrived after: 10 seconds
result arrived after: 10 seconds
result arrived after: 10 seconds
result arrived after: 10 seconds
result arrived after: 10 seconds
result arrived after: 10 seconds

5voto

Vinod Srivastav Punkte 3046

Le site yield Schlüsselwort wird in der Aufzählung/Iteration verwendet, wenn die Funktion mehr als eine Ausgabe zurückgeben soll. Ich möchte dies ganz einfach zitieren Beispiel A :

# example A
def getNumber():
    for r in range(1,10):
        return r

Die obige Funktion liefert nur 1 auch wenn sie mehrfach aufgerufen wird. Wenn wir nun ersetzen return mit yield wie in Beispiel B :

# example B
def getNumber():
    for r in range(1,10):
        yield r

Es wird zurückgegeben 1 beim ersten Aufruf 2 bei erneutem Aufruf dann 3 , 4 und es wird bis 10 erhöht.

Obwohl die Beispiel B ist konzeptionell richtig, aber der Aufruf in python 3 müssen wir Folgendes tun:

g = getNumber() #instance
print(next(g)) #will print 1
print(next(g)) #will print 2
print(next(g)) #will print 3

# so to assign it to a variables
v = getNumber()
v1 = next(v) #v1 will have 1
v2 = next(v) #v2 will have 2
v3 = next(v) #v3 will have 3

3voto

Siva Sankar Punkte 1374

Funktion - gibt zurück.

Generator - Renditen (enthält eine oder mehrere Renditen und null oder mehr Erträge).

names = ['Sam', 'Sarah', 'Thomas', 'James']

# Using function
def greet(name) :
    return f'Hi, my name is {name}.'

for each_name in names:
    print(greet(each_name))

# Output:   
>>>Hi, my name is Sam.
>>>Hi, my name is Sarah.
>>>Hi, my name is Thomas.
>>>Hi, my name is James.

# using generator
def greetings(names) :
    for each_name in names:
        yield f'Hi, my name is {each_name}.'

for greet_name in greetings(names):
    print (greet_name)

# Output:    
>>>Hi, my name is Sam.
>>>Hi, my name is Sarah.
>>>Hi, my name is Thomas.
>>>Hi, my name is James.

Ein Generator sieht aus wie eine Funktion, verhält sich aber wie ein Iterator.

Ein Generator setzt die Ausführung an der Stelle fort, an der er abgesetzt (oder aufgegeben) wurde. Wenn die Funktion wieder aufgenommen wird, setzt sie die Ausführung unmittelbar nach dem letzten Yield-Lauf fort. Dadurch kann der Code eine Reihe von Werten im Laufe der Zeit erzeugen, anstatt sie alle auf einmal zu berechnen und sie wie eine Liste zurückzusenden.

def function():
    yield 1 # return this first
    yield 2 # start continue from here (yield don't execute above code once executed)
    yield 3 # give this at last (yield don't execute above code once executed)

for processed_data in function(): 
    print(processed_data)

#Output:

>>>1
>>>2
>>>3

Anmerkung: Yield sollte nicht in der try ... finally-Konstruktion enthalten sein.

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