Réponses:
Oui, les deux andet les oropé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, oropé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 <= zest équivalent àx < y and y <= z, sauf qu'ilyn'est évalué qu'une seule fois (mais dans les deux caszn'est pas évalué du tout lorsqu'ilx < ys'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 ( Trueou False). Par exemple:
L'opération
x and ydonne 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' oropérateur retourne la valeur la plus à gauche pour laquelle bool(value)== Truesinon 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.
0sont 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__).