Ich habe ein Listenverständnis in Python, in dem jede Iteration eine Ausnahme auslösen kann.
Zum Beispiel , wenn ich habe:
eggs = (1,3,0,3,2)
[1/egg for egg in eggs]
Ich werde eine ZeroDivisionError
Ausnahme im 3. Element bekommen.
Wie kann ich mit dieser Ausnahme umgehen und die Ausführung des Listenverständnisses fortsetzen?
Ich kann mir nur vorstellen, eine Hilfsfunktion zu verwenden:
def spam(egg):
try:
return 1/egg
except ZeroDivisionError:
# handle division by zero error
# leave empty for now
pass
Aber das sieht für mich etwas umständlich aus.
Gibt es eine bessere Möglichkeit, dies in Python zu tun?
Hinweis: Dies ist ein einfaches Beispiel (siehe " zum Beispiel " oben), das ich erfunden habe, weil mein reales Beispiel einen Kontext erfordert. Ich bin nicht daran interessiert, Fehler durch Teilen durch Null zu vermeiden, sondern Ausnahmen in einem Listenverständnis zu behandeln.
python
exception
list-comprehension
Nathan Fellman
quelle
quelle
[1/egg except ZeroDivisionError: None for egg in (1,3,0,3,2)]
. Aber es ist immer noch im Entwurfsmodus. Mein Bauchgefühl ist, dass es nicht akzeptiert wird. Imho-Ausdrücke können zu chaotisch werden (Überprüfung mehrerer Ausnahmen, komplexere Kombinationen (mehrere logische Operatoren, komplexe Verständnisse usw.)ndarray
mit den entsprechenden Einstellungen in verwenden könnennp.seterr
. Das würde dazu führen1/0 = nan
. Mir ist jedoch klar, dass sich dies nicht auf andere Situationen verallgemeinert, in denen dieses Bedürfnis entsteht.Antworten:
In Python gibt es keinen integrierten Ausdruck, mit dem Sie eine Ausnahme ignorieren können (oder bei Ausnahmen alternative Werte & c zurückgeben können). Daher ist es buchstäblich unmöglich, "Ausnahmen in einem Listenverständnis zu behandeln", da ein Listenverständnis ein Ausdruck ist enthält keinen anderen Ausdruck, nichts weiter (dh keine Anweisungen und nur Anweisungen können Ausnahmen abfangen / ignorieren / behandeln).
Funktionsaufrufe sind Ausdrücke, und die Funktionskörper können alle gewünschten Anweisungen enthalten. Daher ist das Delegieren der Auswertung des ausnahmegefährdeten Unterausdrucks an eine Funktion, wie Sie bemerkt haben, eine mögliche Problemumgehung (andere sind, wenn möglich, möglich prüft Werte, die Ausnahmen hervorrufen können, wie auch in anderen Antworten vorgeschlagen).
Die richtigen Antworten auf die Frage "wie man mit Ausnahmen in einem Listenverständnis umgeht" drücken alle einen Teil all dieser Wahrheit aus: 1) wörtlich, dh lexikalisch im Verständnis selbst, kann man nicht; 2) In der Praxis delegieren Sie den Job an eine Funktion oder suchen nach fehleranfälligen Werten, wenn dies möglich ist. Ihre wiederholte Behauptung, dies sei keine Antwort, ist daher unbegründet.
quelle
[x[1] for x in list except IndexError pass]
. Konnte der Interpreter keine temporäre Funktion zum Ausprobieren erstellenx[1]
?Mir ist klar, dass diese Frage ziemlich alt ist, aber Sie können auch eine allgemeine Funktion erstellen, um dies zu vereinfachen:
Dann, nach Ihrem Verständnis:
Sie können die Standardhandle-Funktion natürlich beliebig gestalten (sagen Sie, Sie möchten standardmäßig lieber "Keine" zurückgeben).
Hoffe das hilft dir oder zukünftigen Zuschauern dieser Frage!
Hinweis: In Python 3 würde ich nur das Argument-Schlüsselwort 'handle' verwenden und es am Ende der Argumentliste einfügen. Dies würde das tatsächliche Weitergeben von Argumenten und dergleichen durch Fang viel natürlicher machen.
quelle
args
undkwargs
Durchlaufen. Auf diese Weise können Sie beispielsweiseegg
anstelle eines fest codierten0
oder einer Ausnahme, wie Sie dies tun, zurückkehren.handle
nach zu platzieren**kwarg
und bekam eineSyntaxError
. Meinst du dereferenzieren alskwargs.get('handle',e)
?Sie können verwenden
Dadurch werden einfach Elemente übersprungen, die Null sind.
quelle
Nein, es gibt keinen besseren Weg. In vielen Fällen können Sie Vermeidung anwenden, wie es Peter tut
Ihre andere Möglichkeit besteht darin, kein Verständnis zu verwenden
Es liegt an Ihnen, zu entscheiden, ob dies umständlicher ist oder nicht
quelle
Ich denke, eine Hilfsfunktion, wie sie von demjenigen vorgeschlagen wird, der die erste Frage stellt, und auch von Bryan Head, ist gut und überhaupt nicht umständlich. Eine einzige Zeile magischen Codes, die die ganze Arbeit erledigt, ist einfach nicht immer möglich, daher ist eine Hilfsfunktion eine perfekte Lösung, wenn man
for
Schleifen vermeiden möchte . Ich würde es jedoch zu diesem ändern:Die Ausgabe wird dies sein
[(1/1, None), (1/3, None), (None, ZeroDivisionError), (1/3, None), (1/2, None)]
. Mit dieser Antwort haben Sie die volle Kontrolle darüber, wie Sie möchten.quelle
Either
Typ in einigen funktionalen Programmiersprachen (wie Scala) sehr ähnlich, in denen einEither
Wert des einen oder anderen Typs enthalten kann, jedoch nicht beide. Der einzige Unterschied besteht darin, dass es in diesen Sprachen idiomatisch ist, den Fehler auf der linken Seite und den Wert auf der rechten Seite zu platzieren. Hier ist ein Artikel mit weiteren Informationen .Ich habe keine Antwort gesehen, die dies erwähnt. Dieses Beispiel wäre jedoch eine Möglichkeit, zu verhindern, dass eine Ausnahme für bekannte Fehlerfälle ausgelöst wird.
quelle