Réponses:
Oui, les deux and
et les or
opérateurs court-circuitent - voir la documentation .
and
, or
:Définissons d'abord une fonction utile pour déterminer si quelque chose est exécuté ou non. Une fonction simple qui accepte un argument, imprime un message et renvoie l'entrée, inchangée.
>>> def fun(i):
... print "executed"
... return i
...
On peut observer le comportement de court-circuit de Python de and
, or
opérateurs dans l'exemple suivant:
>>> fun(1)
executed
1
>>> 1 or fun(1) # due to short-circuiting "executed" not printed
1
>>> 1 and fun(1) # fun(1) called and "executed" printed
executed
1
>>> 0 and fun(1) # due to short-circuiting "executed" not printed
0
Remarque: L'interpréteur considère que les valeurs suivantes signifient false:
False None 0 "" () [] {}
any()
, all()
:Les fonctions any()
et Python all()
prennent également en charge les courts-circuits. Comme indiqué dans les documents; ils évaluent chaque élément d'une séquence dans l'ordre, jusqu'à trouver un résultat permettant une sortie précoce de l'évaluation. Considérez les exemples ci-dessous pour comprendre les deux.
La fonction any()
vérifie si un élément est vrai. Il cesse de s'exécuter dès qu'un True est rencontré et renvoie True.
>>> any(fun(i) for i in [1, 2, 3, 4]) # bool(1) = True
executed
True
>>> any(fun(i) for i in [0, 2, 3, 4])
executed # bool(0) = False
executed # bool(2) = True
True
>>> any(fun(i) for i in [0, 0, 3, 4])
executed
executed
executed
True
La fonction all()
vérifie que tous les éléments sont vrais et arrête de s'exécuter dès qu'un faux est rencontré:
>>> all(fun(i) for i in [0, 0, 3, 4])
executed
False
>>> all(fun(i) for i in [1, 0, 3, 4])
executed
executed
False
De plus, en Python
Les comparaisons peuvent être enchaînées arbitrairement ; par exemple,
x < y <= z
est équivalent àx < y and y <= z
, sauf qu'ily
n'est évalué qu'une seule fois (mais dans les deux casz
n'est pas évalué du tout lorsqu'ilx < y
s'avère faux).
>>> 5 > 6 > fun(3) # same as: 5 > 6 and 6 > fun(3)
False # 5 > 6 is False so fun() not called and "executed" NOT printed
>>> 5 < 6 > fun(3) # 5 < 6 is True
executed # fun(3) called and "executed" printed
True
>>> 4 <= 6 > fun(7) # 4 <= 6 is True
executed # fun(3) called and "executed" printed
False
>>> 5 < fun(6) < 3 # only prints "executed" once
executed
False
>>> 5 < fun(6) and fun(6) < 3 # prints "executed" twice, because the second part executes it again
executed
executed
False
Edit:
Un autre point intéressant à noter : - Logiquement and
, lesor
opérateurs en Python retournent la valeur d' un opérande au lieu d'un booléen ( True
ou False
). Par exemple:
L'opération
x and y
donne le résultatif x is false, then x, else y
Contrairement à d'autres langages, par exemple &&
, les ||
opérateurs en C qui renvoient 0 ou 1.
Exemples:
>>> 3 and 5 # Second operand evaluated and returned
5
>>> 3 and ()
()
>>> () and 5 # Second operand NOT evaluated as first operand () is false
() # so first operand returned
De même, l' or
opérateur retourne la valeur la plus à gauche pour laquelle bool(value)
== True
sinon la valeur la plus fausse à droite (selon le comportement de court-circuit), exemples:
>>> 2 or 5 # left most operand bool(2) == True
2
>>> 0 or 5 # bool(0) == False and bool(5) == True
5
>>> 0 or ()
()
Alors, comment est-ce utile? Un exemple d'utilisation donné dans Practical Python par Magnus Lie Hetland:
Disons qu'un utilisateur est censé entrer son nom, mais peut choisir de ne rien entrer, auquel cas vous souhaitez utiliser la valeur par défaut '<unknown>'
. Vous pouvez utiliser une instruction if, mais vous pouvez également énoncer les choses très succinctement:
In [171]: name = raw_input('Enter Name: ') or '<Unkown>'
Enter Name:
In [172]: name
Out[172]: '<Unkown>'
En d'autres termes, si la valeur de retour de raw_input est vraie (pas une chaîne vide), elle est affectée à name (rien ne change); sinon, la valeur par défaut '<unknown>'
est affectée à name
.
0
sont falsy (il est donc pas seulement 0
, il est 0.0
, 0j
, decimal.Decimal(0)
, fractions.Fraction(0)
, etc.), comme toutes les collections de longueur 0
(donc au - dessus de ce que vous avez énumérés, b''
[PY3], u''
[AP2] et set()
/ frozenset()
sont tous les prédéfinis qui sont évalués comme étant faux), mais les types définis par l'utilisateur / tiers peuvent définir les leurs (avec __bool__
[Py3] / __nonzero__
[Py2] directement ou indirectement en définissant __len__
).