Cursus
En programmation, nous devons souvent prendre des décisions à partir de plusieurs conditions. Par exemple, nous pouvons vouloir exécuter une action donnée uniquement si plusieurs conditions sont réunies simultanément. À l’inverse, nous pouvons déclencher une action alternative si au moins l’une de ces conditions est remplie.
Python met à disposition un ensemble d’opérateurs logiques – and, or, not – pour couvrir ces cas.
Dans ce tutoriel, nous verrons comment fonctionnent les opérateurs logiques de Python et comment les utiliser en programmation et en data science. Notez que nous utiliserons les mots en majuscules AND, OR et NOT pour désigner ces opérateurs de manière conceptuelle, et que nous ferons référence aux mots-clés Python avec cette convention : and, or et not.
Si vous cherchez un programme Python structuré, découvrez ce parcours de compétences en six cours : Python Programming.
Avant d’entrer dans le détail, voici une réponse très rapide pour les plus pressés.
Réponse rapide : que sont les opérateurs logiques en Python ?
Les opérateurs logiques de Python (and, or, not) sont des mots-clés spéciaux qui jouent le rôle de conjonctions dans votre code : ils relient et évaluent plusieurs conditions au sein d’une même expression.
Considérez cet exemple :
temperature = 25
is_sunny = True
if temperature > 20 and is_sunny:
print("It's a perfect day for a picnic!")
It's a perfect day for a picnic!
Ici, l’opérateur and garantit que le message n’est affiché que si les deux conditions sont remplies : la température est supérieure à 20 degrés et il fait beau.
Regardons un autre exemple avec l’opérateur or :
has_umbrella = False
if is_sunny or has_umbrella:
print("Let's go for a walk!")
Let's go for a walk!
Dans ce cas, nous sortirons marcher si soit il fait beau, soit nous avons un parapluie.
Enfin, l’opérateur not inverse la valeur de vérité d’une condition :
if not is_sunny:
print("Maybe we should stay indoors.")
Ici, le message n’est affiché que s’il ne fait pas beau.
Les opérateurs logiques offrent une manière concise et puissante d’exprimer des conditions complexes, et permettent à nos programmes de décider en fonction de multiples facteurs. Passons maintenant à une analyse plus approfondie, en commençant par l’opérateur logique and.
Python : l’opérateur and
En logique booléenne, l’opération AND compare deux valeurs ou expressions. Elle renvoie vrai uniquement si les deux valeurs sont vraies. Si l’une ou les deux valeurs sont fausses, le résultat de l’opération AND est faux. Voici un résumé du comportement de AND :
|
Opération |
Valeur renvoyée |
|
true AND true |
true |
|
true AND false |
false |
|
false AND true |
false |
|
false AND false |
false |
Nous pouvons recréer cette table de vérité avec l’opérateur and de Python :
options = True, False
for a in options:
for b in options:
print(f"{a} and {b} gives {a and b}")
True and True gives True
True and False gives False
False and True gives False
False and False gives False
La variable options contient les deux valeurs booléennes. Les boucles for imbriquées parcourent deux fois ces options pour créer toutes les permutations de True et False.
Souvent, les expressions utilisées comme opérandes de and incluent des opérateurs de comparaison ou d’égalité :
names = "James", "Bob", "David", "Jane", "Kate", "Mary"
for name in names:
if len(name) < 5 and name[0] == "J":
print(name)
Jane
Le prénom n’est affiché que s’il contient moins de cinq lettres et commence par "J". Les deux critères doivent être remplis.
Les opérateurs de comparaison et d’égalité, tels que < et ==, renvoient True ou False.
Cependant, l’opérateur and de Python fonctionne avec tout type de données et pas uniquement avec les booléens True et False. La valeur renvoyée peut elle aussi être de n’importe quel type.
Explorons plus en détail l’opérateur and de Python dans cette section. Commençons par la notion de « vrai/faux implicite ».
Python : truthy et falsy
Tout objet Python peut être converti en booléen via la fonction intégrée bool(). Un objet est dit « truthy » si bool(object) renvoie True. Pour un objet « falsy », bool(object) renvoie False.
L’opérateur and de Python s’appuie sur le caractère truthy de ses opérandes. Si les deux opérandes sont truthy, and renvoie aussi une valeur truthy. Si l’un ou l’autre (ou les deux) sont falsy, and renvoie une valeur falsy. Voyons quelques exemples :
if 42 and "python":
print("Both operands are truthy")
else:
print("One or both operands are falsy")
Both operands are truthy
Considérons maintenant cet exemple :
if 42 and "":
print("Both operands are truthy")
else:
print("One or both operands are falsy")
One or both operands are falsy
Et regardons ce dernier exemple :
if 0 and "python":
print("Both operands are truthy")
else:
print("One or both operands are falsy")
One or both operands are falsy
Les types numériques, comme les entiers et les flottants, sont truthy s’ils sont non nuls et falsy lorsqu’ils valent zéro. Les séquences, comme les chaînes, sont truthy lorsqu’elles sont non vides et falsy lorsqu’elles sont vides.
Ainsi, seul le premier des trois exemples ci-dessus satisfait la condition « deux opérandes truthy » pour que l’opérateur and évalue l’expression comme truthy.
L’opérateur and ne renvoie pas toujours une valeur booléenne. Une expression comportant and peut aussi s’évaluer à l’une des opérandes. Approfondissons avec les mêmes exemples, mais en évaluant directement les expressions plutôt que de les placer dans un if :
print(42 and "python")
print(42 and "")
print(0 and "python")
python
0
Voyez-vous ce qu’il se passe ?
Commençons par le dernier exemple, dont les opérandes sont 0 et "python". L’opérateur and recherche deux opérandes truthy. Comme la première vaut 0, elle est falsy. Il est inutile d’évaluer la seconde : l’expression entière sera falsy quelle que soit sa valeur.
Toutefois, l’opérateur and ne renvoie pas False. Il renvoie directement la première opérande. Comme celle-ci est falsy, l’expression and s’évalue globalement à falsy. Cela ne pose aucun problème en Python : lorsqu’un vrai/faux est requis, Python utilise le caractère truthy/falsy de l’objet.
Dans le premier exemple, la première opérande est 42, donc truthy. Le programme évalue la seconde opérande et la renvoie. Comme il s’agit de la chaîne "python", qui est truthy, l’expression entière est truthy.
Dans le deuxième exemple, la première opérande est aussi 42. Étant truthy, le programme évalue et renvoie la seconde opérande, qui est la chaîne vide. La chaîne vide est falsy ; l’expression and est donc falsy.
Quand la première opérande est truthy, l’opérateur and renvoie toujours la valeur de la seconde opérande, qu’elle soit truthy ou falsy.
Quand la première opérande est falsy, Python n’évalue pas la seconde. C’est ce qu’on appelle le court-circuit (short-circuit), une forme d’évaluation paresseuse. Vous pouvez le constater avec le code suivant :
0 and 5/0
0
La seconde opérande est 5/0, qui lèverait normalement une ZeroDivisionError. Mais l’expression 5/0 n’est pas évaluée ici, car la première opérande est falsy. L’exception n’est jamais levée.
Exemple : la boutique en ligne des programmeurs
Prenons un exemple simple, inspiré d’un cas réel. Les transactions d’une boutique en ligne dédiée aux programmeurs sont enregistrées et exposées via une API. Les données sont converties en une liste de dictionnaires. Chaque élément de la liste représente une transaction, et chaque transaction est un dictionnaire contenant les informations pertinentes :
data = [
{"Item": "Python Book", "Price": 50, "Quantity": 1, "Success": True},
{"Item": "Coffee Machine", "Price": 125, "Quantity": 1, "Success": False},
{"Item": "Headphones", "Price": 250, "Quantity": 1, "Success": True},
{"Item": "Cables", "Price": 15.99, "Quantity": 3, "Success": True},
]
Chaque transaction inclut le nom de l’article et son prix, la quantité commandée, et l’indication de réussite de la transaction.
Supposons que nous ayons besoin des transactions réussies pour des articles à 100 $ ou plus. Nous pouvons utiliser l’opérateur and pour filtrer les lignes voulues :
for item in data:
if item["Success"] and item["Price"] >= 100:
print(item)
{'Item': 'Headphones', 'Price': 250, 'Quantity': 1, 'Success': True}
La sortie montre la seule transaction qui satisfait les deux critères. Pour chaque élément de la liste, l’instruction if vérifie la « vérité » de deux expressions :
- La valeur associée à la clé
"Success"est soitTrue, soitFalse. - L’opérateur « supérieur ou égal à » dans
item["Price"] >= 100renvoie égalementTrueouFalse.
Le livre Python et les câbles ne répondent pas au critère de prix car ils sont sous la barre des 100 $. La machine à café dépasse ce seuil, mais la transaction a échoué ; elle est donc exclue de l’affichage.
Nous reviendrons sur cet exemple plus loin dans le tutoriel.
Dans la section suivante, nous nous concentrons sur l’opérateur or.
Python : l’opérateur or
En logique booléenne, l’opérateur OR prend deux opérandes. Il renvoie vrai si au moins l’une des opérandes est vraie :
|
Opération |
Valeur renvoyée |
|
true OR true |
true |
|
true OR false |
true |
|
false OR true |
true |
|
false OR false |
false |
Nous pouvons recréer cette table de vérité avec l’opérateur or de Python :
options = True, False
for a in options:
for b in options:
print(f"{a} or {b} gives {a or b}")
True or True gives True
True or False gives True
False or True gives True
False or False gives False
Reprenons aussi l’exemple des prénoms vu plus haut, en remplaçant l’opérateur and par or :
names = "James", "Bob", "David", "Jane", "Kate", "Mary"
for name in names:
if len(name) < 5 or name[0] == "J":
print(name)
James
Bob
Jane
Kate
Mary
L’instruction if contient maintenant une expression or. La boucle for affiche donc tous les prénoms qui ont moins de cinq lettres ou qui commencent par la lettre "J". La chaîne "Jane" satisfait les deux conditions. Les autres prénoms affichés remplissent l’une des deux.
Opérateur Python or : truthy et falsy
L’opérateur or tient lui aussi compte des valeurs truthy et falsy, et pas uniquement des booléens True et False. Voyons quelques exemples :
if 42 or [10, 20, 30]:
print("At least one operand is truthy")
else:
print("None of the operands is truthy")
At least one operand is truthy
Considérons maintenant cet exemple :
if 42 or []:
print("At least one operand is truthy")
else:
print("None of the operands is truthy")
At least one operand is truthy
Et regardons enfin cet exemple :
if 0 or []:
print("At least one operand is truthy")
else:
print("None of the operands is truthy")
None of the operands is truthy
Dans le premier cas, l’entier 42 et la liste non vide [10, 20, 30] sont truthy. Puisque or n’exige qu’une opérande truthy, l’expression entière est truthy.
Dans le deuxième cas, 42 est truthy mais la liste vide [] est falsy, car il s’agit d’une séquence vide. Comme l’une des deux opérandes est truthy, l’expression or est truthy.
Dans le dernier cas, 0 et [] sont tous deux falsy. L’expression entière est donc falsy.
L’opérateur or utilise lui aussi le court-circuit pour éviter des évaluations inutiles. Illustrons cela :
print(42 or [10, 20, 30])
print(42 or [])
print([] or 42)
print([] or 0)
42
42
42
0
Dans le premier exemple, la première opérande 42 est truthy. Comme or n’a besoin que d’une opérande truthy pour déterminer le résultat, cette première valeur est renvoyée immédiatement. La seconde n’est pas évaluée car sa valeur n’influe pas sur le résultat. L’opérateur or renvoie la première opérande, 42, et non le booléen True. En Python, toute valeur truthy équivaut, dans des contextes comme les instructions if et while, au booléen True.
Dans le deuxième exemple, la première opérande est également 42, et l’expression renvoie cet entier même si la seconde opérande est falsy.
Dans les troisième et quatrième exemples, la première opérande est une liste vide, donc falsy. La seconde opérande est alors renvoyée dans les deux cas.
Exemple : la boutique en ligne des programmeurs
Revenons aux transactions de la boutique en ligne. Voici les quatre transactions utilisées dans l’exemple :
data = [
{"Item": "Python Book", "Price": 50, "Quantity": 1, "Success": True},
{"Item": "Coffee Machine", "Price": 125, "Quantity": 1, "Success": False},
{"Item": "Headphones", "Price": 250, "Quantity": 1, "Success": True},
{"Item": "Cables", "Price": 15.99, "Quantity": 3, "Success": True},
]
Vous devez identifier des transactions à analyser pour mieux comprendre le comportement client. Vous cherchez les transactions qui ont échoué ou qui incluent un article à moins de 75 $. Comme vous avez deux conditions et qu’il suffit d’en satisfaire au moins une, vous pouvez utiliser l’opérateur or :
for item in data:
if item["Success"] == False or item["Price"] < 75:
print(item)
{'Item': 'Python Book', 'Price': 50, 'Quantity': 1, 'Success': True}
{'Item': 'Coffee Machine', 'Price': 125, 'Quantity': 1, 'Success': False}
{'Item': 'Cables', 'Price': 15.99, 'Quantity': 3, 'Success': True}
Cette boucle for affiche les lignes qui correspondent à au moins une des conditions. Le livre Python et les câbles sont inclus car leur prix est inférieur à 75 $. La machine à café est incluse car la transaction a échoué.
Il existe une autre manière de filtrer les transactions échouées, que nous verrons dans la section suivante.
Python : l’opérateur not
L’opérateur NOT diffère de AND et OR car il ne nécessite qu’une seule opérande. NOT convertit vrai en faux et inversement. Voici la table de vérité de NOT :
|
Opération |
Valeur renvoyée |
|
NOT true |
false |
|
NOT false |
true |
Nous pouvons reproduire cela avec l’opérateur not de Python :
options = True, False
for a in options:
print(f"not {a} evaluates to {not a}")
not True evaluates to False
not False evaluates to True
Opérateur Python not : truthy et falsy
Comme pour and et or, l’opérande utilisée avec not n’a pas besoin d’être un booléen. Tout objet étant soit truthy, soit falsy, il peut être utilisé avec not.
if not "python":
print("The `if` statement evaluated as `True`")
else:
print("The `if` statement evaluated as `False`")
The `if` statement evaluated as `False`
Regardons aussi cet exemple :
if not "":
print("The `if` statement evaluated as `True`")
else:
print("The `if` statement evaluated as `False`")
The `if` statement evaluated as `True`
Les valeurs truthy sont converties en False avec l’opérateur not, et les valeurs falsy en True.
Contrairement à and et or, l’opérateur not renvoie toujours un booléen :
print(not "python")
print(not "")
False
True
Exemple : la boutique en ligne des programmeurs
Dans les sections précédentes, nous avons utilisé les transactions d’une boutique en ligne. Nous voulons ici afficher toutes les transactions échouées. Une option consiste à utiliser l’opérateur d’égalité == pour vérifier si data["Success"] vaut False. Mais nous pouvons aussi utiliser l’opérateur not :
data = [
{"Item": "Python Book", "Price": 50, "Quantity": 1, "Success": True},
{"Item": "Coffee Machine", "Price": 125, "Quantity": 1, "Success": False},
{"Item": "Headphones", "Price": 250, "Quantity": 1, "Success": True},
{"Item": "Cables", "Price": 15.99, "Quantity": 3, "Success": True},
]
for item in data:
if not item["Success"]:
print(item)
{'Item': 'Coffee Machine', 'Price': 125, 'Quantity': 1, 'Success': False}
Comme item["Success"] est égal à False pour les transactions échouées, not item["Success"] renvoie True. La boucle for affiche donc ces transactions :
Dans la section suivante, nous verrons comment combiner plusieurs opérateurs logiques dans une seule expression.
Python : la précédence des opérateurs
Dans les exemples vus jusque-là, nous n’avons utilisé qu’un seul opérateur logique à la fois. Voyons maintenant ce qui se passe lorsque l’on combine plusieurs opérateurs logiques au sein d’une même expression.
Python : and est prioritaire sur or
Poursuivons avec les transactions de la boutique en ligne. Essayons l’instruction conditionnelle suivante :
data = [
{"Item": "Python Book", "Price": 50, "Quantity": 1, "Success": True},
{"Item": "Coffee Machine", "Price": 125, "Quantity": 1, "Success": False},
{"Item": "Headphones", "Price": 250, "Quantity": 1, "Success": True},
{"Item": "Cables", "Price": 15.99, "Quantity": 3, "Success": True},
]
for item in data:
if item["Price"] > 100 or item["Quantity"] > 2 and item["Success"]:
print(item)
{'Item': 'Coffee Machine', 'Price': 125, 'Quantity': 1, 'Success': False}
{'Item': 'Headphones', 'Price': 250, 'Quantity': 1, 'Success': True}
{'Item': 'Cables', 'Price': 15.99, 'Quantity': 3, 'Success': True}
L’instruction if contient deux opérateurs logiques. Avant d’examiner comment Python évalue cette expression, reformulons-la en français : Si le prix de l’article est supérieur à 100 $ ou si la quantité vendue est supérieure à deux et que la vente a réussi, alors affichez l’article.
Cette phrase est ambiguë sans ponctuation supplémentaire, et peut rester confuse même avec plus de virgules. Par exemple, faut-il inclure la transaction de la machine à café ? Le prix de l’article dépasse bien le seuil, mais la transaction a échoué.
Python lève cette ambiguïté en donnant la priorité à l’opérateur and sur l’opérateur or. Autrement dit, l’expression avec and est évaluée en premier, et son résultat est utilisé dans l’expression avec or.
Ainsi, l’expression item["Quantity"] > 2 and item["Success"] est évaluée d’abord. Elle renvoie une valeur truthy uniquement pour la transaction incluant des câbles. Elle est falsy pour les autres articles.
La valeur issue de l’expression and est ensuite utilisée avec l’opérateur or. L’expression or renvoie une valeur truthy pour tout article truthy avec l’expression and — ici seulement la transaction avec des câbles — et pour tout article dont le prix dépasse 100 $. Deux articles dépassent ce seuil : la machine à café et le casque.
Python : parenthèses et opérateurs logiques
Mais que faire si nous voulons les transactions avec un article à plus de 100 $ ou avec une quantité supérieure à deux, tout en imposant que la transaction soit réussie ? Dans ce cas, nous voulons que l’expression or soit prioritaire sur and et soit évaluée en premier. Nous pouvons y parvenir en ajoutant des parenthèses autour de l’expression or :
for item in data:
if (item["Price"] > 100 or item["Quantity"] > 2) and item["Success"]:
print(item)
{'Item': 'Headphones', 'Price': 250, 'Quantity': 1, 'Success': True}
{'Item': 'Cables', 'Price': 15.99, 'Quantity': 3, 'Success': True}
Les parenthèses donnent la priorité à l’expression or. La transaction de la machine à café n’est plus incluse, car elle est falsy pour le second opérande du and.
Python : not est prioritaire sur and et or
L’opérateur not est prioritaire sur and et or. Il est donc évalué avant les deux autres.
Considérons l’instruction if suivante, qui inclut not et and :
for item in data:
if not item["Success"] and item["Price"] > 100:
print(item)
{'Item': 'Coffee Machine', 'Price': 125, 'Quantity': 1, 'Success': False}
Comme not est évalué en premier, l’expression applique d’abord not à item["Success"]. La valeur de cette expression not sert ensuite de première opérande à l’expression and. Seule l’entrée « machine à café » satisfait la condition : c’est la seule transaction échouée avec un prix supérieur à 100 $.
Nous pouvons toutefois donner la priorité à l’opérateur and en utilisant des parenthèses :
for item in data:
if not (item["Success"] and item["Price"] > 100):
print(item)
{'Item': 'Python Book', 'Price': 50, 'Quantity': 1, 'Success': True}
{'Item': 'Coffee Machine', 'Price': 125, 'Quantity': 1, 'Success': False}
{'Item': 'Cables', 'Price': 15.99, 'Quantity': 3, 'Success': True}
Ici, l’expression and est évaluée d’abord. Seule l’entrée avec le casque s’évalue à True, car c’est la seule transaction réussie avec un prix supérieur à 100 $. Mais nous appliquons un not devant l’expression entre parenthèses ; le code affiche donc les trois autres transactions.
De manière générale, si une expression devient trop complexe à cause d’un trop grand nombre d’opérateurs, il est préférable de la scinder pour en améliorer la lisibilité.
Conclusion
Les opérateurs logiques and, or et not sont largement utilisés en programmation et en data science. Ils reproduisent le comportement des opérateurs booléens AND, OR et NOT, bien connus en logique et en mathématiques.
Cependant, les opérateurs Python acceptent tout type d’objet, pas uniquement des booléens. Les opérateurs and et or utilisent l’évaluation en court-circuit et renvoient l’un des opérandes comme résultat.
Les opérateurs logiques de Python sont des outils essentiels pour filtrer des données, identifier des caractéristiques dans des jeux de données et créer des règles complexes pilotant le flux d’un programme. Pour aller plus loin, découvrez ce parcours carrière en neuf cours : Data Analyst With Python.
J'ai étudié la physique et les mathématiques au niveau UG à l'université de Malte. J'ai ensuite déménagé à Londres et obtenu un doctorat en physique à l'Imperial College. J'ai travaillé sur de nouvelles techniques optiques pour obtenir des images de la rétine humaine. Aujourd'hui, je me concentre sur l'écriture, la communication et l'enseignement de Python.
FAQ sur les opérateurs logiques en Python
Puis-je utiliser l’opérateur and pour tester plusieurs conditions à la fois ?
Oui, vous pouvez chaîner plusieurs conditions avec l’opérateur and. Par exemple : if x > 5 and x < 10 and x != 7.
Quelle est la différence entre l’opérateur and et l’opérateur AND bit à bit (&) ?
L’opérateur and effectue une opération logique AND sur des valeurs booléennes et ne renvoie True que si les deux opérandes sont True. L’opérateur AND bit à bit (&) réalise une opération AND bit à bit sur la représentation binaire de valeurs entières.
Python propose-t-il les opérateurs && et || comme certains autres langages ?
Non. Python utilise les mots-clés and et or au lieu des symboles && et || pour les opérations logiques.
