Ich habe eine Generatorfunktion wie die folgende:
def myfunct():
...
yield result
Der übliche Weg, diese Funktion aufzurufen, wäre:
for r in myfunct():
dostuff(r)
Meine Frage, gibt es eine Möglichkeit, immer nur ein Element aus dem Generator zu holen, wann immer ich möchte? Zum Beispiel möchte ich etwas tun wie:
while True:
...
if something:
my_element = pick_just_one_element(myfunct())
dostuff(my_element)
...
python
iterator
generator
python-2.x
Alexandros
quelle
quelle
next(gen, default)
kann auch verwendet werden, um dieStopIteration
Ausnahme zu vermeiden . Zum Beispielnext(g, None)
ergibt ein Generator von Strings nach Abschluss der Iteration entweder einen String oder None.next(g)
. Dies wird intern nenneng.__next__()
, aber Sie wirklich nicht zu befürchten , dass haben, so wie man in der Regel nicht , dass es egallen(a)
intern telefonierena.__len__()
.g.next()
istg.__next__()
in py3k. Das eingebaute Systemnext(iterator)
gibt es seit Python 2.6 und sollte in allen neuen Python-Codes verwendet werden. Eine Backimplementierung ist trivial, wenn Sie py <= 2.5 unterstützen müssen.Verwenden Sie zum Auswählen nur eines Elements eines Generators
break
in einerfor
Anweisung oderlist(itertools.islice(gen, 1))
Nach Ihrem Beispiel (im wahrsten Sinne des Wortes) können Sie Folgendes tun:
Wenn Sie " nur ein Element vom [einmal generierten] Generator erhalten möchten , wann immer ich möchte " (ich nehme an, 50% sind die ursprüngliche Absicht und die häufigste Absicht), dann:
Auf diese Weise kann die explizite Verwendung von
generator.next()
vermieden werden, und die Behandlung am Ende der Eingabe erfordert keine (kryptische)StopIteration
Ausnahmebehandlung oder zusätzliche Standardwertvergleiche.Der Abschnitt mit
else:
derfor
Anweisung wird nur benötigt, wenn Sie im Falle eines Generatorendes etwas Besonderes tun möchten.Hinweis zu
next()
/.next()
:In Python3 wurde die
.next()
Methode.__next__()
aus gutem Grund umbenannt: Sie gilt als Low-Level (PEP 3114). Vor Python 2.6 existierte die eingebaute Funktionnext()
nicht. Und es wurde sogar diskutiert,next()
auf dasoperator
Modul umzusteigen (was klug gewesen wäre), da es nur selten benötigt wird und die eingebauten Namen fragwürdig aufgeblasen sind.Die Verwendung
next()
ohne Standard ist immer noch eine sehr einfache Übung - das Werfen der KryptikStopIteration
wie ein Blitz aus heiterem Himmel im normalen Anwendungscode offen. Und die Verwendungnext()
mit Standard-Sentinel - was am besten die einzige Option für einnext()
direktes In sein solltebuiltins
- ist begrenzt und führt häufig zu ungerader nicht-pythonischer Logik / Lesbarkeit.Fazit: Die Verwendung von next () sollte sehr selten sein - wie die Verwendung von Funktionen des
operator
Moduls. Mitfor x in iterator
,islice
,list(iterator)
und anderen Funktionen einen Iterator nahtlos zu akzeptieren ist die natürliche Art und Weise von Iteratoren auf Anwendungsebene mit - und ganz immer möglich.next()
ist Low-Level, ein zusätzliches Konzept, nicht offensichtlich - wie die Frage dieses Threads zeigt. Während zB die Verwendungbreak
infor
ist konventionell.quelle
mySeq.head
?Ich glaube nicht, dass es eine bequeme Möglichkeit gibt, einen beliebigen Wert von einem Generator abzurufen. Der Generator bietet eine next () -Methode, um sich selbst zu durchlaufen, aber die vollständige Sequenz wird nicht sofort erzeugt, um Speicherplatz zu sparen. Das ist der funktionale Unterschied zwischen einem Generator und einer Liste.
quelle
Für diejenigen unter Ihnen, die diese Antworten nach einem vollständigen Arbeitsbeispiel für Python3 durchsuchen ... Nun, los geht's:
Dies gibt aus:
quelle
Generator ist eine Funktion, die einen Iterator erzeugt. Verwenden Sie daher, sobald Sie eine Iteratorinstanz haben, next () , um das nächste Element aus dem Iterator abzurufen. Verwenden Sie beispielsweise die Funktion next (), um das erste Element abzurufen, und verwenden Sie es später
for in
, um verbleibende Elemente zu verarbeiten:quelle
Stellen Sie sicher, dass Sie die Ausnahme abfangen, die ausgelöst wird, nachdem das letzte Element übernommen wurde
quelle
Ich glaube, der einzige Weg ist, eine Liste vom Iterator zu erhalten und dann das gewünschte Element aus dieser Liste zu erhalten.
quelle
myfunct()
eine große Anzahl von Werten generiert wird), da Sie die integrierte Funktion verwenden könnennext
, um den nächsten generierten Wert abzurufen.