Python & AI Tutorials Logo
Programmation Python

9. Combiner des conditions avec la logique booléenne

Au chapitre 7, nous avons appris les valeurs booléennes et les conditions simples en utilisant des opérateurs de comparaison. Au chapitre 8, nous avons utilisé ces conditions pour prendre des décisions avec des instructions if. Mais les programmes du monde réel ont souvent besoin de vérifier plusieurs conditions à la fois. Faut-il accorder l’accès si l’utilisateur a le bon mot de passe et est connecté ? Faut-il afficher un avertissement si la température est trop chaude ou trop froide ? Faut-il continuer si le fichier n’est pas vide ?

Python fournit trois opérateurs logiques (logical operators) qui nous permettent de combiner et de modifier des valeurs booléennes : and, or et not. Ces opérateurs sont les briques de base pour exprimer une logique de prise de décision complexe dans vos programmes.

9.1) Opérateurs logiques and, or, et not

Les trois opérateurs logiques fonctionnent avec des valeurs booléennes (ou des valeurs qui peuvent être traitées comme des booléens) pour produire de nouveaux résultats booléens.

9.1.1) L’opérateur and

L’opérateur and renvoie True uniquement lorsque les deux opérandes sont vraies. Si l’un des opérandes est faux, l’expression entière est fausse.

python
# Les deux conditions doivent être vraies
age = 25
has_license = True
 
can_rent_car = age >= 21 and has_license
print(can_rent_car)  # Output: True
 
# Si l’une des conditions est fausse, le résultat est False
age = 18
can_rent_car = age >= 21 and has_license
print(can_rent_car)  # Output: False

Considérez and comme un gardien strict : toutes les conditions doivent être remplies pour que la vérification globale réussisse.

Table de vérité pour and :

Opérande gaucheOpérande droitRésultat
TrueTrueTrue
TrueFalseFalse
FalseTrueFalse
FalseFalseFalse

9.1.2) L’opérateur or

L’opérateur or renvoie True lorsque au moins un opérande est vrai. Il ne renvoie False que lorsque les deux opérandes sont faux.

python
# Au moins une condition doit être vraie
is_weekend = True
is_holiday = False
 
can_sleep_in = is_weekend or is_holiday
print(can_sleep_in)  # Output: True
 
# Les deux conditions sont fausses
is_weekend = False
is_holiday = False
can_sleep_in = is_weekend or is_holiday
print(can_sleep_in)  # Output: False

Considérez or comme un gardien indulgent : vous n’avez besoin de satisfaire qu’une condition pour passer.

Table de vérité pour or :

Opérande gaucheOpérande droitRésultat
TrueTrueTrue
TrueFalseTrue
FalseTrueTrue
FalseFalseFalse

Voici un exemple pratique pour un système d’éligibilité à une réduction :

python
# Le client obtient une réduction s’il est étudiant OU senior
age = 68
is_student = False
 
gets_discount = is_student or age >= 65
print(f"Eligible for discount: {gets_discount}")  # Output: Eligible for discount: True
 
# Un autre client
age = 30
is_student = False
gets_discount = is_student or age >= 65
print(f"Eligible for discount: {gets_discount}")  # Output: Eligible for discount: False

Le premier client est éligible parce qu’il remplit l’un des critères (senior), même s’il n’est pas étudiant.

9.1.3) L’opérateur not

L’opérateur not est un opérateur unaire (unary operator) (il fonctionne sur un seul opérande) qui inverse une valeur booléenne. Il transforme True en False et False en True.

python
is_raining = False
is_sunny = not is_raining
print(is_sunny)  # Output: True
 
is_raining = True
is_sunny = not is_raining
print(is_sunny)  # Output: False

Table de vérité pour not :

OpérandeRésultat
TrueFalse
FalseTrue

L’opérateur not est particulièrement utile lorsque vous voulez vérifier l’opposé d’une condition :

python
# Vérifier qu’un fichier n’est PAS vide
file_size = 0
is_empty = file_size == 0
is_not_empty = not is_empty
print(f"File has content: {is_not_empty}")  # Output: File has content: False
 
# Vérifier que l’utilisateur n’est PAS connecté
is_logged_in = False
needs_login_prompt = not is_logged_in
print(f"Show login prompt: {needs_login_prompt}")  # Output: Show login prompt: True

9.1.4) Combiner plusieurs opérateurs logiques

Vous pouvez combiner plusieurs opérateurs logiques dans une seule expression pour construire des conditions plus sophistiquées :

python
# Boutique en ligne : livraison gratuite si la commande dépasse 50 $ OU si le client est membre premium
# ET si les articles sont en stock
order_total = 45.00
is_premium = True
in_stock = True
 
gets_free_shipping = (order_total >= 50 or is_premium) and in_stock
print(f"Free shipping: {gets_free_shipping}")  # Output: Free shipping: True

Traçons cette évaluation :

  1. order_total >= 50 s’évalue à False (45.00 n’est pas >= 50)
  2. is_premium est True
  3. False or True s’évalue à True
  4. in_stock est True
  5. True and True s’évalue à True

Voici un autre exemple avec du contrôle d’accès :

python
# L’utilisateur peut accéder au panneau d’administration s’il est admin
# ET (s’il est sur le réseau interne OU s’il utilise un VPN)
is_admin = True
on_internal_network = False
using_vpn = True
 
can_access_admin = is_admin and (on_internal_network or using_vpn)
print(f"Can access admin panel: {can_access_admin}")  # Output: Can access admin panel: True

Remarquez les parenthèses autour de (on_internal_network or using_vpn). Elles sont importantes car elles contrôlent l’ordre d’évaluation, tout comme les parenthèses dans les expressions arithmétiques.

9.2) Priorité des opérateurs dans les expressions booléennes (ordre Not, And, Or)

Lorsque vous combinez plusieurs opérateurs logiques sans parenthèses, Python suit des règles de priorité spécifiques pour déterminer l’ordre d’évaluation. Comprendre ces règles vous aide à écrire des conditions correctes et à éviter des bugs subtils.

9.2.1) La hiérarchie de priorité

Python évalue les opérateurs logiques dans cet ordre (de la priorité la plus élevée à la plus faible) :

  1. not (priorité la plus élevée)
  2. and (priorité intermédiaire)
  3. or (priorité la plus faible)

Cela signifie que not est évalué en premier, puis and, et enfin or.

python
# Sans parenthèses, la priorité détermine l’ordre
result = True or False and False
print(result)  # Output: True
 
# Comment Python évalue cela :
# Étape 1 : False and False → False (and a une priorité plus élevée que or)
# Étape 2 : True or False → True

Voyons cela étape par étape avec un exemple plus détaillé :

python
is_weekend = False
is_holiday = True
has_work = True
 
# Expression : not has_work or is_weekend and is_holiday
free_time = not has_work or is_weekend and is_holiday
 
# Ordre d’évaluation :
# Étape 1 : not has_work → not True → False
# Étape 2 : is_weekend and is_holiday → False and True → False
# Étape 3 : False or False → False
print(f"Has free time: {free_time}")  # Output: Has free time: False

9.2.2) Utiliser des parenthèses pour plus de clarté

Même si vous comprenez les règles de priorité, l’utilisation de parenthèses rend votre code plus clair et évite les erreurs. Les parenthèses remplacent la priorité par défaut et rendent vos intentions explicites.

python
# Ambigu sans parenthèses
result = True or False and False
print(result)  # Output: True
 
# Clair avec des parenthèses - que voulait-on vraiment dire ?
result = (True or False) and False
print(result)  # Output: False
 
result = True or (False and False)
print(result)  # Output: True

Ces deux expressions produisent des résultats différents ! Les parenthèses changent complètement le sens.

9.2.3) Opérateurs de comparaison et opérateurs logiques ensemble

Les opérateurs de comparaison (comme <, >, ==, !=) ont une priorité plus élevée que les opérateurs logiques. Cela signifie que les comparaisons sont évaluées avant les opérations logiques.

python
age = 25
income = 50000
 
# Pas besoin de parenthèses autour des comparaisons
eligible = age >= 18 and income >= 30000
print(f"Eligible for loan: {eligible}")  # Output: Eligible for loan: True
 
# Python l’évalue ainsi :
# Étape 1 : age >= 18 → True
# Étape 2 : income >= 30000 → True
# Étape 3 : True and True → True

9.3) Évaluation en court-circuit

Python utilise l’évaluation en court-circuit (short-circuit evaluation) lorsqu’il évalue des expressions booléennes avec and et or. Cela signifie que Python s’arrête dès qu’il connaît le résultat final, en sautant potentiellement l’évaluation des opérandes suivants. Ce comportement est à la fois une optimisation de performance et une technique de programmation utile.

9.3.1) Comment and court-circuite

Avec l’opérateur and, si l’opérande de gauche est False, Python sait que l’expression entière doit être False (car les deux opérandes doivent être vrais pour que and renvoie True). Par conséquent, Python n’évalue pas du tout l’opérande de droite.

python
# Démonstration simple
x = 5
result = x < 3 and x > 10
print(result)  # Output: False
 
# Évaluation de Python :
# Étape 1 : x < 3 → 5 < 3 → False
# Étape 2 : Comme le côté gauche est False, ne pas évaluer x > 10
# Étape 3 : Renvoyer False

Voici un exemple pratique montrant pourquoi l’évaluation en court-circuit est importante :

python
# Vérifier si un nombre est divisible - éviter la division par zéro
numerator = 100
denominator = 0
 
# Ceci est sûr grâce à l’évaluation en court-circuit
# Si denominator vaut 0, la division n’a jamais lieu
is_divisible = denominator != 0 and numerator % denominator == 0
print(f"Is divisible: {is_divisible}")  # Output: Is divisible: False
 
# Sans l’évaluation en court-circuit, cela provoquerait une erreur :
# denominator = 0
# result = numerator % denominator  # ZeroDivisionError!

L’expression denominator != 0 s’évalue à False, donc Python n’évalue jamais numerator % denominator, ce qui provoquerait une erreur de division par zéro.

Voyons un autre exemple avec des opérations sur les chaînes :

python
# Vérifier des propriétés de chaîne en toute sécurité
text = ""
 
# Vérifier que text n’est pas vide ET que le premier caractère est en majuscule
# Sûr car si text est vide, on n’essaie jamais d’accéder à text[0]
has_uppercase_start = len(text) > 0 and text[0].isupper()
print(f"Starts with uppercase: {has_uppercase_start}")  # Output: Starts with uppercase: False
 
# Si on essayait cela sans vérifier la longueur :
# text = ""
# result = text[0].isupper()  # IndexError: string index out of range

9.3.2) Comment or court-circuite

Avec l’opérateur or, si l’opérande de gauche est True, Python sait que l’expression entière doit être True (car il suffit qu’au moins un opérande soit vrai). Par conséquent, Python n’évalue pas l’opérande de droite.

python
# Démonstration simple
x = 15
result = x > 10 or x < 5
print(result)  # Output: True
 
# Évaluation de Python :
# Étape 1 : x > 10 → 15 > 10 → True
# Étape 2 : Comme le côté gauche est True, ne pas évaluer x < 5
# Étape 3 : Renvoyer True

9.3.3) Applications pratiques de l’évaluation en court-circuit

Éviter des erreurs :

python
# Accéder à des éléments de liste en toute sécurité
numbers = [1, 2, 3]
index = 5
 
# Vérifier que index est valide avant d’accéder
is_valid = index < len(numbers) and numbers[index] > 0
print(f"Valid and positive: {is_valid}")  # Output: Valid and positive: False
 
# Sans court-circuit, cela planterait :
# is_valid = numbers[index] > 0  # IndexError!

Vérifier plusieurs conditions efficacement :

python
# Validation de formulaire - s’arrêter à la première erreur
email = "user@example.com"
password = "pass"
age = 25
 
# Vérifier chaque exigence dans l’ordre le plus susceptible d’échouer
valid_form = (
    len(email) > 0 and              # Vérification rapide
    "@" in email and                # Vérification rapide
    len(password) >= 8 and          # Vérification rapide
    age >= 18                       # Vérification rapide
)
print(f"Form valid: {valid_form}")  # Output: Form valid: False
# S’arrête à la vérification de la longueur du mot de passe, n’évalue pas age

Non

Oui

Oui

Non

Expression and

Côté gauche True ?

Retourner False
Ignorer le côté droit

Évaluer le côté droit

Retourner le résultat du côté droit

Expression or

Côté gauche True ?

Retourner True
Ignorer le côté droit

Évaluer le côté droit

Retourner le résultat du côté droit

9.4) Ce que renvoient les opérateurs and et or avec des opérandes non booléens, et pièges courants des expressions booléennes

Jusqu’ici, nous avons vu and, or et not fonctionner avec des valeurs booléennes. Mais les opérateurs logiques de Python ont un comportement intéressant : ils peuvent fonctionner avec n’importe quelles valeurs, pas seulement True et False. Comprendre ce comportement vous aide à écrire du code plus concis et à éviter des erreurs courantes.

9.4.1) Comprendre les valeurs truthy et falsy (rappel)

Comme nous l’avons appris au chapitre 7, Python traite de nombreuses valeurs non booléennes comme étant soit « truthy » soit « falsy » dans des contextes booléens :

Valeurs falsy (traitées comme False) :

  • False
  • None
  • 0 (zéro de n’importe quel type numérique)
  • "" (chaîne vide)
  • [] (liste vide)
  • {} (dictionnaire vide)
  • () (tuple vide)

Valeurs truthy (traitées comme True) :

  • True
  • Tout nombre non nul
  • Toute chaîne non vide
  • Toute collection non vide
python
# Démontrer le comportement truthy/falsy
if "hello":
    print("Non-empty strings are truthy")  # Output: Non-empty strings are truthy
 
if 0:
    print("This won't print")  # Zero is falsy
else:
    print("Zero is falsy")  # Output: Zero is falsy
 
if [1, 2, 3]:
    print("Non-empty lists are truthy")  # Output: Non-empty lists are truthy

9.4.2) Ce que and renvoie réellement

L’opérateur and ne renvoie pas toujours True ou False. À la place, il renvoie l’un de ses opérandes :

  • Si l’opérande de gauche est falsy, and renvoie l’opérande de gauche (sans évaluer celui de droite)
  • Si l’opérande de gauche est truthy, and renvoie l’opérande de droite
python
# and renvoie la première valeur falsy, ou la dernière valeur si toutes sont truthy
result = 5 and 10
print(result)  # Output: 10
 
result = 0 and 10
print(result)  # Output: 0
 
result = "hello" and "world"
print(result)  # Output: world
 
result = "" and "world"
print(result)  # Output: (empty string)
 
result = None and "world"
print(result)  # Output: None

Traçons ces exemples :

python
# Exemple 1 : Les deux sont truthy
result = 5 and 10
# Étape 1 : 5 est truthy, donc évaluer le côté droit
# Étape 2 : Renvoyer la valeur du côté droit : 10
print(result)  # Output: 10
 
# Exemple 2 : Le côté gauche est falsy
result = 0 and 10
# Étape 1 : 0 est falsy, donc le renvoyer immédiatement
# Étape 2 : Ne pas évaluer le côté droit
print(result)  # Output: 0
 
# Exemple 3 : Deux chaînes truthy
result = "hello" and "world"
# Étape 1 : "hello" est truthy, donc évaluer le côté droit
# Étape 2 : Renvoyer la valeur du côté droit : "world"
print(result)  # Output: world

9.4.3) Ce que or renvoie réellement

De même, l’opérateur or renvoie l’un de ses opérandes :

  • Si l’opérande de gauche est truthy, or renvoie l’opérande de gauche (sans évaluer celui de droite)
  • Si l’opérande de gauche est falsy, or renvoie l’opérande de droite
python
# or renvoie la première valeur truthy, ou la dernière valeur si toutes sont falsy
result = 5 or 10
print(result)  # Output: 5
 
result = 0 or 10
print(result)  # Output: 10
 
result = "" or "default"
print(result)  # Output: default
 
result = "hello" or "world"
print(result)  # Output: hello
 
result = None or 0
print(result)  # Output: 0

Traçons ces exemples :

python
# Exemple 1 : Le côté gauche est truthy
result = 5 or 10
# Étape 1 : 5 est truthy, donc le renvoyer immédiatement
# Étape 2 : Ne pas évaluer le côté droit
print(result)  # Output: 5
 
# Exemple 2 : Le côté gauche est falsy
result = 0 or 10
# Étape 1 : 0 est falsy, donc évaluer le côté droit
# Étape 2 : Renvoyer la valeur du côté droit : 10
print(result)  # Output: 10
 
# Exemple 3 : Les deux sont falsy
result = None or 0
# Étape 1 : None est falsy, donc évaluer le côté droit
# Étape 2 : Renvoyer la valeur du côté droit : 0 (même si elle est aussi falsy)
print(result)  # Output: 0

9.4.4) Utilisations pratiques de or pour des valeurs par défaut

Un motif courant consiste à utiliser or pour fournir des valeurs par défaut :

python
# Préférences utilisateur avec valeurs par défaut
user_theme = ""  # L’utilisateur n’a pas défini de thème
theme = user_theme or "light"
print(f"Theme: {theme}")  # Output: Theme: light
 
user_theme = "dark"
theme = user_theme or "light"
print(f"Theme: {theme}")  # Output: Theme: dark
 
# Valeurs de configuration
max_retries = None  # Non configuré
retries = max_retries or 3
print(f"Retries: {retries}")  # Output: Retries: 3
 
max_retries = 5
retries = max_retries or 3
print(f"Retries: {retries}")  # Output: Retries: 5

Ce motif fonctionne parce que si le côté gauche est falsy (chaîne vide, None, 0, etc.), or renvoie le côté droit (la valeur par défaut).

and

or

Oui

Non

Oui

Non

Opérateur logique avec non-booléen

Type d’opérateur

Côté gauche falsy ?

Côté gauche truthy ?

Retourner la valeur de gauche

Retourner la valeur de droite

Retourner la valeur de gauche

Retourner la valeur de droite

9.4.12) Résumé de ce que renvoient les opérateurs

Voici un résumé complet de ce que renvoie chaque opérateur logique :

Opérateur and :

  • Renvoie le premier opérande falsy
  • Si tous les opérandes sont truthy, renvoie le dernier opérande
  • Utilise l’évaluation en court-circuit (s’arrête à la première valeur falsy)

Opérateur or :

  • Renvoie le premier opérande truthy
  • Si tous les opérandes sont falsy, renvoie le dernier opérande
  • Utilise l’évaluation en court-circuit (s’arrête à la première valeur truthy)

Opérateur not :

  • Renvoie toujours un booléen (True ou False)
  • not convertit l’opérande en booléen, puis l’inverse
python
# Démontrer les trois opérateurs
print(5 and 10)           # Output: 10 (both truthy, return last)
print(0 and 10)           # Output: 0 (first falsy, return it)
print(5 or 10)            # Output: 5 (first truthy, return it)
print(0 or 10)            # Output: 10 (first falsy, evaluate second)
print(not 5)              # Output: False (5 is truthy, not returns boolean)
print(not 0)              # Output: True (0 is falsy, not returns boolean)
print(not "")             # Output: True (empty string is falsy)
print(not "hello")        # Output: False (non-empty string is truthy)

Comprendre ces comportements vous aide à écrire du code plus concis et plus pythonique, mais privilégiez toujours la clarté. Si l’utilisation de ces fonctionnalités rend votre code plus difficile à comprendre, il vaut mieux être explicite.


Dans ce chapitre, nous avons exploré comment combiner des conditions simples en une logique booléenne complexe en utilisant les opérateurs and, or et not de Python. Nous avons appris la priorité des opérateurs, l’évaluation en court-circuit, et le comportement surprenant des opérateurs logiques avec des valeurs non booléennes. Nous avons aussi examiné les pièges courants et les bonnes pratiques pour écrire des expressions booléennes claires et correctes.

Ces outils vous permettent d’exprimer une logique de prise de décision sophistiquée dans vos programmes. Combinés avec les instructions if du chapitre 8, vous pouvez désormais gérer pratiquement toute logique conditionnelle dont vos programmes ont besoin. Dans le prochain chapitre, nous explorerons les expressions conditionnelles, qui offrent une manière compacte de choisir entre deux valeurs en fonction d’une condition.

© 2025. Primesoft Co., Ltd.
support@primesoft.ai