Ich habe die Graph-Traversierung als eine Generatorfunktion implementiert, die den besuchten Knoten liefert.
Manchmal muss der Benutzer der Traversierungsfunktion mitteilen, dass die Kanten, die von einem bestimmten Knoten ausgehen, nicht befolgt werden sollten; Um dies zu unterstützen, überprüft der Traversal den zurückgesendeten Wert (mit dem Generator send()
method), und wenn es True
ist, betrachtet er den Knoten als ein Blatt für Traversierungszwecke.
Das Problem ist, dass die einfachste Benutzerschleife ziemlich lang ist:
%Vor%Gibt es eine Möglichkeit, dies zu verbessern?
Ich dachte, so etwas sollte funktionieren:
%Vor%aber ich fühle, dass mir das Wissen über eine Python-Syntax fehlt.
Ich sehe keine Möglichkeit, dies in einer normalen for
-Schleife zu tun. Sie könnten jedoch einen anderen Generator erstellen, der einen anderen Generator iteriert und dabei eine "follow-function" verwendet, um zu ermitteln, ob dem aktuellen Element gefolgt werden soll. Dadurch werden die komplizierten Teile Ihres Codes in eine separate Funktion eingekapselt.
Um den Client-Code zu vereinfachen, könnten Sie einen gewöhnlichen bsf()
Generator verwenden und das node.isleaf
Attribut darin überprüfen:
Der Nachteil ist, dass node
veränderbar ist. Oder Sie übergeben eine gemeinsame Datenstruktur, die Blattknoten verfolgt: leaf[node] = process(node)
, wobei leaf
dictionary in bfs()
früher übergeben wird.
Wenn Sie .send()
method explizit verwenden möchten; Sie müssen mit StopIteration
umgehen. Siehe PEP 479 - Ändern der StopIteration-Behandlung in Generatoren . Sie könnten es in einer Hilfsfunktion verstecken:
Beispiel:
%Vor%Ich sehe das nicht als häufigen Anwendungsfall, betrachte dies als den ursprünglichen Generator:
%Vor% Wenn der Wert von should_break
immer auf Basis eines Funktionsaufrufs mit x
berechnet wird, dann schreibe den Generator einfach so:
Allerdings denke ich normalerweise an den Code, der die generierten Werte so verarbeitet, dass sie in die Schleife geschrieben werden (sonst, was ist der Sinn, überhaupt eine Schleife zu haben?)
Was Sie wirklich zu tun scheinen, ist einen Generator zu erstellen, bei dem der Aufruf der __next__
-Methode wirklich send(process(LAST_VALUE))
impliziert, was mit einer Klasse implementiert werden kann:
Allerdings wird dies immer noch nicht so häufig verwendet. Ich wäre völlig in Ordnung mit einer while
-Schleife, obwohl ich den .send
-Aufruf an die Spitze gesetzt hätte:
Und Sie könnten das in ein try: ... except StopIteration:pass
einbinden, obwohl ich finde, dass es einfach besser ist, auf einen Fehler zu warten, um es mit einem Kontextmanager auszudrücken:
Ich habe festgestellt, dass meine Frage eine einzeilige Antwort gehabt hätte, indem ich die erweiterte "continue" -Anweisung verwendet habe, die in frühere Version von PEP 342 :
%Vor%Während jedoch PEP 342 akzeptiert wurde, wurde dieses spezielle Feature nach diese Juni 2005 Diskussion zwischen Raymond und Guido:
Raymond Hettinger hat gesagt:
Lassen Sie mich als starke -1 für "EXPR fortfahren" aufzeichnen. Das for-loop ist unser grundlegendstes Konstrukt und leicht zu verstehen gegenwärtige Form. Das gleiche gilt für "weiter" und "break" was haben den zusätzlichen Vorteil einer Lernkurve nahe Null für Menschen Migration von anderen Sprachen.
Jeder Drang, diese grundlegenden Aussagen zu komplizieren, sollte ernst genommen werden überprüft und gehalten zu hohen Standards der Klarheit, Erklärbarkeit, Offensichtlichkeit, Nützlichkeit und Notwendigkeit. IMO, es versagt die meisten von denen Tests.
Ich würde mich nicht darauf freuen, im Tutorial "EXPR fortführen" zu erklären und denke, es würde sich als Anti-Feature herausstellen.
[...] Das korrekte Argument gegen "EXPR fortfahren" ist das dort sind noch keine Anwendungsfälle; wenn es einen guten Anwendungsfall gäbe, die Erklärung würde leicht folgen.
Guido
Wenn Python-Core-Entwickler seither ihre Meinung über den Nutzen von erweitertem "continue" geändert haben, könnte dies vielleicht in einem zukünftigen PEP wieder eingeführt werden. Aber angesichts eines nahezu identischen Anwendungsfalls, wie er in dieser Frage bereits im zitierten Thread diskutiert wurde und nicht überzeugend gefunden wurde, erscheint dies unwahrscheinlich.
Tags und Links python python-3.x generator python-3.5