Ich habe die folgende Lambda-Funktion:
%Vor%Es sollte eine leere Zeichenfolge zurückgeben, wenn es None als das Argument erhält, oder das Argument, wenn es nicht None ist.
Zum Beispiel:
%Vor%Wenn ich f (None) anstelle einer leeren Zeichenfolge anrufe, bekomme ich keine. Ich habe den Typ der Funktion ausgedruckt, die zurückgegeben wurde, und ich habe NoneType erhalten. Ich habe Schnur erwartet.
type ('') gibt einen String zurück, deshalb würde ich gerne wissen, warum das Lambda keine leere Zeichenfolge zurückgibt, wenn ich None als Argument überlasse.
Ich bin mit lambdas ziemlich neu, also hätte ich vielleicht einige Dinge über ihre Arbeitsweise missverstanden.
Das Problem ist, dass Python die leere Zeichenfolge als False behandelt. Wenn Sie None an Ihre Funktion übergeben, wird Folgendes ausgewertet:
%Vor%was (effektiv) wird:
%Vor%dann:
%Vor%und schließlich:
%Vor%Eine Lösung wäre:
%Vor%Wenn Sie wissen, dass x entweder eine Zeichenkette oder None ist, können Sie die Tatsache nutzen, dass None in Python auch ein False-Wert ist:
%Vor%Es ist nicht Lambdas, die hier das Problem sind. Es ist der pythonische if / else Ausdruck, den du dort benutzt.
(condition) and (expression1) or (expression2)
bedeutet meistens die (condition) ? (expression1) : (expression2)
, die Sie erwarten würden, außer wenn expression1
zu False ausgewertet wird.
Das liegt daran, dass das Ganze in der richtigen Reihenfolge ausgewertet wird. Wenn condition
fehlschlägt, wird expression1
ausgewertet. Wenn es True
ist, wird es aufgrund der Kurzschlussauswertung zurückgegeben, daher das erwartete Verhalten. Wenn nicht, wird expression2
zurückgegeben. ''
ergibt False.
Python gibt and
einen höheren Vorrang als or
, daher fallen die Klammern hier:
Wenn None
übergeben wurde, wird (True and '') or None
. Die Booleschen Operatoren von Python arbeiten, indem sie das eine oder andere Argument zurückgeben (woher dieser kleine Trick stammt), also reduziert sich dies auf '' or None
und schließlich auf None
.
Dieser kleine Trick stammt aus der Zeit vor Python 2.5, ohne den bedingten Operator . Die Einschränkung, auf die Sie gerade gestoßen sind, ist, dass sie sich nicht wie erwartet verhält, wenn True
branch einen False
-Wert hat. Wenn Sie sich nicht mit Python ≤ 2.4 beschäftigen, verwenden Sie einfach den bedingten Operator.