TL; DR
Wir fassen zunächst die beiden Verhaltensweisen der beiden logischen Operatoren and
und zusammen or
. Diese Redewendungen bilden die Grundlage unserer nachfolgenden Diskussion.
and
Gibt den ersten Falsy-Wert zurück, falls vorhanden, andernfalls den letzten Wert im Ausdruck.
or
Geben Sie den ersten Truthy-Wert zurück, falls vorhanden, andernfalls den letzten Wert im Ausdruck.
Das Verhalten ist auch in den Dokumenten zusammengefasst , insbesondere in dieser Tabelle:
Der einzige Operator, der unabhängig von seinen Operanden einen booleschen Wert zurückgibt, ist der not
Operator.
"Truthiness" - und "Truthy" -Bewertungen
Die Aussage
len(args) and max(args) - min(args)
Ist eine sehr pythonische, prägnante (und wahrscheinlich weniger lesbare) Art zu sagen: "Wenn args
nicht leer, geben Sie das Ergebnis von zurück max(args) - min(args)
", andernfalls kehren Sie zurück 0
. Im Allgemeinen ist es eine präzisere Darstellung eines if-else
Ausdrucks. Beispielsweise,
exp1 and exp2
Sollte (grob) bedeuten:
r1 = exp1
if r1:
r1 = exp2
Oder gleichwertig,
r1 = exp1 if exp1 else exp2
Ähnlich,
exp1 or exp2
Ist äquivalent zu,
r1 = exp1
if not r1:
r1 = exp2
Wo exp1
und exp2
sind beliebige Python-Objekte oder Ausdrücke, die ein Objekt zurückgeben. Der Schlüssel zum Verständnis der Verwendung der Logik and
und der or
Operatoren besteht darin, zu verstehen, dass sie nicht darauf beschränkt sind, boolesche Werte zu bearbeiten oder zurückzugeben. Hier kann jedes Objekt mit einem Wahrheitswert getestet werden. Dazu gehört auch int
, str
, list
, dict
, tuple
, set
, NoneType
, und Benutzerobjekte definiert. Auch die Kurzschlussregeln gelten weiterhin.
Aber was ist Wahrhaftigkeit?
Es bezieht sich darauf, wie Objekte ausgewertet werden, wenn sie in bedingten Ausdrücken verwendet werden. @Patrick Haugh fasst die Wahrhaftigkeit in diesem Beitrag gut zusammen .
Alle Werte gelten als "wahr", mit Ausnahme der folgenden Werte, die "falsch" sind:
None
False
0
0.0
0j
Decimal(0)
Fraction(0, 1)
[]
- ein leeres list
{}
- ein leeres dict
()
- ein leeres tuple
''
- ein leeres str
b''
- ein leeres bytes
set()
- ein leeres set
- eine leere
range
, wierange(0)
- Objekte für die
obj.__bool__()
kehrt zurück False
obj.__len__()
kehrt zurück 0
Ein "wahrheitsgemäßer" Wert erfüllt die von if
oder while
Anweisungen durchgeführte Prüfung . Wir verwenden "wahr" und "falsch", um von den bool
Werten True
und zu unterscheiden
False
.
Wie and
funktioniert
Wir bauen auf der Frage von OP auf, um eine Diskussion darüber zu führen, wie diese Operatoren in diesen Fällen vorgehen.
Gegeben eine Funktion mit der Definition
def foo(*args):
...
Wie gebe ich die Differenz zwischen dem minimalen und dem maximalen Wert in einer Liste mit null oder mehr Argumenten zurück?
Das Minimum und Maximum zu finden ist einfach (nutzen Sie die eingebauten Funktionen!). Der einzige Nachteil hierbei ist die angemessene Behandlung des Eckfalls, in dem die Argumentliste leer sein könnte (z. B. Aufruf foo()
). Dank des and
Betreibers können wir beides in einer einzigen Zeile erledigen :
def foo(*args):
return len(args) and max(args) - min(args)
foo(1, 2, 3, 4, 5)
# 4
foo()
# 0
Da and
verwendet wird, muss der zweite Ausdruck auch ausgewertet werden, wenn der erste ist True
. Beachten Sie, dass der Rückgabewert immer das Ergebnis des zweiten Ausdrucks ist, wenn der erste Ausdruck als wahr bewertet wird . Wenn der erste Ausdruck als falsch bewertet wird, ist das zurückgegebene Ergebnis das Ergebnis des ersten Ausdrucks.
In der obigen Funktion ist If, foo
das ein oder mehrere Argumente empfängt, len(args)
größer als 0
(eine positive Zahl), sodass das zurückgegebene Ergebnis lautet max(args) - min(args)
. OTOH, wenn keine Argumente übergeben werden, len(args)
ist 0
die Falsy ist und 0
zurückgegeben wird.
Beachten Sie, dass eine alternative Möglichkeit zum Schreiben dieser Funktion Folgendes wäre:
def foo(*args):
if not len(args):
return 0
return max(args) - min(args)
Oder genauer gesagt:
def foo(*args):
return 0 if not args else max(args) - min(args)
Wenn natürlich keine dieser Funktionen eine Typprüfung durchführt, verlassen Sie sich nicht auf die Einfachheit dieser Konstrukte , es sei denn, Sie vertrauen vollständig auf die bereitgestellten Eingaben .
Wie or
funktioniert
Ich erkläre die Arbeitsweise or
auf ähnliche Weise anhand eines erfundenen Beispiels.
Gegeben eine Funktion mit der Definition
def foo(*args):
...
Wie würden Sie vervollständigen foo
, um alle Zahlen zurückzugeben 9000
?
Wir verwenden or
hier den Eckfall. Wir definieren foo
als:
def foo(*args):
return [x for x in args if x > 9000] or 'No number over 9000!'
foo(9004, 1, 2, 500)
# [9004]
foo(1, 2, 3, 4)
# 'No number over 9000!'
foo
führt eine Filterung der Liste durch, um alle Zahlen beizubehalten 9000
. Wenn es solche Zahlen gibt, ist das Ergebnis des Listenverständnisses eine nicht leere Liste, die Truthy ist, also wird sie zurückgegeben (Kurzschluss in Aktion hier). Wenn es keine solchen Zahlen gibt, ist das Ergebnis der []
Listenkompensation Falsy. Der zweite Ausdruck wird nun ausgewertet (eine nicht leere Zeichenfolge) und zurückgegeben.
Unter Verwendung von Bedingungen könnten wir diese Funktion wie folgt umschreiben:
def foo(*args):
r = [x for x in args if x > 9000]
if not r:
return 'No number over 9000!'
return r
Nach wie vor ist diese Struktur hinsichtlich der Fehlerbehandlung flexibler.
and
(sowieor
) ist nicht darauf beschränkt, mit booleschen Werten zu arbeiten oder diese zurückzugeben.