437 votes

Python supporte-t-il le court-circuitage ?

Python supporte-t-il le court-circuitage dans les expressions booléennes ?

1 votes

414voto

Alex Martelli Points 330805

Yep, les deux and y or les opérateurs court-circuitent -- voir les docs .

255voto

Grijesh Chauhan Points 28442

Comportement de court-circuitage de l'opérateur and , or :

Commençons par définir 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 Le comportement de court-circuitage de Python de and , or 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

Note : Les valeurs suivantes sont considérées par l'interpréteur comme signifiant faux :

        False    None    0    ""    ()    []     {}

Comportement de court-circuitage en fonction : any() , all() :

Python any() y all() supportent également les courts-circuits. Comme indiqué dans la documentation, elles évaluent chaque élément d'une séquence dans l'ordre, jusqu'à ce qu'elles trouvent un résultat permettant une sortie anticipée de l'évaluation. Considérez les exemples ci-dessous pour comprendre les deux.

La fonction any() vérifie si un élément est True. Il arrête l'exécution dès qu'un True est rencontré et retourne 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 l'exécution 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

Comportement de court-circuitage dans la comparaison en chaîne :

En outre, dans Python

Les comparaisons peuvent être enchaînées de manière arbitraire ; par exemple, x < y <= z est équivalent à x < y and y <= z sauf que y n'est évalué qu'une seule fois (mais dans les deux cas z n'est pas évalué du tout lorsque x < y s'avère être fausse).

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 :- Logique and , or en Python renvoie la valeur de l'opérateur valeur au lieu d'un booléen ( True ou False ). Par exemple :

Opération x and y donne le résultat if x is false, then x, else y

Contrairement à d'autres langues, par exemple && , || opérateurs en C qui retournent soit 0 soit 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, or l'opérateur retourne la valeur la plus à gauche pour laquelle bool(value) == True sinon la valeur la plus fausse à droite (selon le comportement du 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, en quoi est-ce utile ? Un exemple est donné dans Python pratique Par Magnus Lie Hetland :
Disons qu'un utilisateur est censé saisir son nom, mais qu'il peut choisir de ne rien saisir, auquel cas vous souhaitez utiliser la valeur par défaut. '<Unknown>' . Vous pouvez utiliser une instruction "si", mais vous pouvez aussi énoncer les choses de manière très succincte :

In [171]: name = raw_input('Enter Name: ') or '<Unknown>'
Enter Name: 

In [172]: name
Out[172]: '<Unknown>'

En d'autres termes, si la valeur de retour de raw_input est vrai (ce n'est pas une chaîne vide), il est affecté au nom (rien ne change) ; sinon, la valeur par défaut de l'option '<Unknown>' est affecté à name .

3 votes

Une petite critique : La liste explicite des valeurs fausses est légèrement trompeuse. Tout peut avoir une ou plusieurs valeurs falsy. Par convention, tous les types numériques avec la valeur 0 sont fausses (donc ce n'est pas seulement 0 c'est 0.0 , 0j , decimal.Decimal(0) , fractions.Fraction(0) etc.), comme le sont toutes les collections de longueur 0 (donc en plus de ce que vous avez énuméré, b'' [Py3], u'' [Py2] et set() / frozenset() sont tous des built-ins qui sont évalués comme falsy), mais les types définis par l'utilisateur ou par des tiers peuvent définir leurs propres types (avec la fonction __bool__ [Py3]/ __nonzero__ [Py2] directement, ou indirectement en définissant __len__ ).

1 votes

@ShadowRanger ici votre commentaire complètera ma réponse. merci d'avoir ajouté cette note.

0 votes

De plus, python évalue doublement les conditionnels court-circuités, s'ils sont ensuite utilisés comme booléens... à moins qu'ils ne soient dans une instruction if, qui est privilégiée : gist.github.com/earonesty/08e9cbe083a5e0583feb8a34cc538010

59voto

Caprooja Points 130

Oui. Essayez ce qui suit dans votre interpréteur python :

et

>>>False and 3/0
False
>>>True and 3/0
ZeroDivisionError: integer division or modulo by zero

ou

>>>True or 3/0
True
>>>False or 3/0
ZeroDivisionError: integer division or modulo by zero

-1voto

Deekshant Points 101

Oui, Python supporte Évaluation des courts-circuits , évaluation minimale o Évaluation de McCarthy pour les opérateurs booléens. Il est utilisé pour réduire le nombre d'évaluations pour calculer la sortie de l'expression booléenne. Exemple

Fonctions de base

def a(x):
    print('a')
    return x

def b(x):
    print('b')
    return x 

ET

if(a(True) and b(True)):
    print(1,end='\n\n')

if(a(False) and b(True)):
    print(2,end='\n\n') 

AND-OUTPUT

a
b
1

a 

OU

if(a(True) or b(False)):
    print(3,end='\n\n')

if(a(False) or b(True)):
    print(4,end='\n\n') 

OR-OUTPUT

a
3

a
b
4

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X