TL; DR
Wir fassen zunächst die beiden Verhaltensweisen der beiden logischen Operatoren andund 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 notOperator.
"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 argsnicht 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-elseAusdrucks. 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 exp1und exp2sind beliebige Python-Objekte oder Ausdrücke, die ein Objekt zurückgeben. Der Schlüssel zum Verständnis der Verwendung der Logik andund der orOperatoren 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 ifoder while
Anweisungen durchgeführte Prüfung . Wir verwenden "wahr" und "falsch", um von den boolWerten Trueund zu unterscheiden
False.
Wie andfunktioniert
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 andBetreibers 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 andverwendet 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, foodas 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 0die Falsy ist und 0zurü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 orfunktioniert
Ich erkläre die Arbeitsweise orauf ä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 orhier den Eckfall. Wir definieren fooals:
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!'
foofü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.