L’ins­truc­tion if-else en Python (en français : « si-(alors)-sinon ») est un bran­che­ment con­di­tion­nel et donc une structure de contrôle de base. L’uti­li­sa­tion d’un bran­che­ment con­di­tion­nel permet de suivre des chemins de code dif­fé­rents en fonction d’une condition ren­con­trée à l’exécution. Nous ex­pli­quons comment if-else fonc­tionne et est utilisé dans Python.

Cer­ti­fi­cats SSL
Faites le choix de la sécurité
  • Sécurisez vos trans­ferts de données
  • Renforcez la confiance de vos clients
  • Améliorez votre po­si­tion­ne­ment sur Google

Qu’est-ce qu’une ins­truc­tion if-else ?

L’ins­truc­tion if-else est un bran­che­ment con­di­tion­nel. On peut se l’imaginer comme un ai­guil­lage : en présence d’un élément de com­mu­ta­tion, un seul des deux chemins possibles est emprunté. Python est un langage in­ter­prété ; l’in­ter­pré­teur lit les lignes du code source de haut en bas. Dans le cas le plus simple, il en résulte un flux de programme stric­te­ment linéaire : toutes les lignes sont lues, in­ter­pré­tées et exécutées les unes après les autres.

En suivant ce schéma simple, il n’est toutefois pas possible de réaliser des pro­grammes complexes. Ce n’est qu’en utilisant des struc­tures de contrôle que l’on obtient la va­ria­bi­lité du code exécuté né­ces­saire dans la pratique. Un bran­che­ment permet l’exécution con­di­tion­nelle de certaines parties de code. Les autres struc­tures de contrôle utilisées sont notamment les boucles Python for et les boucles Python while, qui per­met­tent l’exécution répétée de parties de code.

Conseil

Apprenez à écrire du code Python grâce à notre tutoriel Python !

Comment fonc­tionne if-else en Python ?

En général, l’ins­truc­tion if-else fonc­tionne en Python de la même manière que dans les autres langages. Il y a cependant quelques par­ti­cu­la­ri­tés spé­ci­fiques à Python. Voyons en détail comment fonc­tionne l’ins­truc­tion if-else en Python et comment elle se comporte par rapport aux autres langages.

Syntaxe générale de l’ins­truc­tion if-else en Python

La syntaxe générale de l’ins­truc­tion if-else peut être exprimée di­rec­te­ment en code Python. Nous dé­fi­nis­sons une condition et, dans le corps de l’ins­truc­tion if, nous dé­fi­nis­sons par exemple un appel de fonction comme chemin de code à suivre lorsque la condition devient vraie. Nous dé­fi­nis­sons également dans le corps else un chemin de code à suivre dans le cas contraire :

if condition:
    if_body()
else:
    else_body()

La condition définie peut être soit vraie (True) soit fausse (False). Nous il­lus­trons le modèle en ins­cri­vant un littéral True ou False di­rec­te­ment comme condition. Il en résulte un flux de programme statique dans lequel il est garanti qu’un seul des deux chemins est emprunté à la fois :

if False:
    # ce code ne sera jamais exécuté
    if_body()
else:
    else_body()
if True:
    if_body()
else:
    # ce code ne sera jamais exécuté
    else_body()

Bien entendu, ce modèle n’est pas pratique, il sert uni­que­ment à illustrer. Au lieu d’une valeur True/False statique, une ex­pres­sion est utilisée comme condition. L’ex­pres­sion est évaluée lors de l’exécution du programme. On dit que l’ex­pres­sion est « évaluée ». Lors de l’éva­lua­tion de l’ex­pres­sion, une valeur de vérité est obtenue. Selon que la valeur de vérité est True ou False, le programme se branche dans l’une ou l’autre direction.

Il est important de com­prendre que la partie else est fa­cul­ta­tive. Le code contenu dans le corps else n’est exécuté que si la condition ne s’applique pas. Cela n’est toutefois pas obli­ga­toire. Souvent, une ins­truc­tion if seule est suf­fi­sante :

if condition:
    if_body()

Une petite remarque sur la no­men­cla­ture : nous avons utilisé les termes « ins­truc­tion » et « ex­pres­sion » sans les expliquer. Il est pourtant important de com­prendre ce que l’on entend par là. Car ces deux notions fon­da­men­tales se re­trou­vent dans tous les langages de pro­gram­ma­tion. Voici un aperçu de la sig­ni­fi­ca­tion de ces termes :

Terme Nom anglais Ex­pli­ca­tion
Ins­truc­tion Statement Action qui est exécutée ; influence gé­né­ra­le­ment le dé­rou­le­ment du programme
Ex­pres­sion Ex­pres­sion Terme qui renvoie une valeur lors de l’éva­lua­tion

In­ter­ro­ger plusieurs con­di­tions ex­clu­sives avec l’ins­truc­tion elif en Python

Outre la célèbre ins­truc­tion if-else en Python, il existe une ins­truc­tion elif ap­pa­ren­tée. Une ins­truc­tion if est suivie de plusieurs ins­truc­tions elif op­tion­nelles, suivies d’un bloc else optionnel. Une ins­truc­tion elif n’est exécutée que si aucune des con­di­tions pré­cé­dentes n’est vraie. Cela garantit que seul un chemin de code unique défini est suivi :

if condition:
    if_body()
elif other_condition:
    elif_body()
elif another_condition:
    another_elif_body()
else:
    else_body()

Voici les règles de cons­truc­tion d’une branche if elif else enchaînée :

Ins­truc­tions de bran­che­ment Nombre en com­bi­nai­son
if exac­te­ment un
elif zéro ou plusieurs
else zéro ou un

Comment utiliser if-else en Python ?

L’ins­truc­tion if-else est une fonc­tion­na­lité de base en Python et dans d’autres langages. Na­tu­rel­le­ment, il existe de nom­breuses pos­si­bi­li­tés d’uti­li­sa­tion. Nous vous pré­sen­tons des exemples courants, ainsi que les meil­leures pratiques et les anti-patterns.

Uti­li­sa­tion correcte de la condition if en Python

Regardons d’abord comment fonc­tionne la condition d’une ins­truc­tion de bran­che­ment. La condition est in­ter­pré­tée comme une ex­pres­sion booléenne qui évalue à l’une des valeurs de vérité True ou False. Il est donc inutile de tester ex­pli­ci­te­ment l’égalité avec un littéral booléen :

if expression == True:
    ...

Même si la com­pa­rai­son explicite avec True n’est pas une véritable erreur, le code ne fait pas pro­fes­sion­nel. Les pro­gram­meurs ex­pé­ri­men­tés écrivent à la place :

if expression:
    ...

Examinons l’anti-pattern à l’aide d’un exemple. Supposons qu’une fonction is_odd() renvoie True pour un nombre si le nombre est impair. Dans le cas contraire, la fonction is_odd renvoie False. Nous utilisons la fonction dans une ins­truc­tion if et affichons un texte cor­res­pon­dant :

if is_odd(number) == True:
    print("The number is odd.")

Imaginons ce qui se passe lors du passage du bran­che­ment avec un nombre impair. D’abord, l’ex­pres­sion 'is_odd(number) == True' évalue en 'True == True'. Cette dernière évalue à son tour en 'True' ; le corps if est exécuté. Il est plus judicieux d’utiliser di­rec­te­ment la valeur booléenne renvoyée par la fonction is_odd comme condition :

if is_odd(number):
    print("The number is odd.")

Exécuter du code optionnel avec l’ins­truc­tion if en Python

Imaginons la situation suivante : nous avons un bloc de code avec une certaine fonction. Les lignes sont exécutées les unes après les autres. Cependant, un élément du code ne doit pas être exécuté à chaque fois, mais uni­que­ment lorsqu’une condition est remplie. Pour mettre en œuvre ce modèle, nous avons sim­ple­ment besoin d’une ins­truc­tion if. Illustrée ici par l’exemple d’une routine d’en­re­gis­tre­ment d’uti­li­sa­teur :

def register_user(user_data, do_newsletter_signup = False):
    # create user account
    user_account = create_account(user_data)
    # sign up for newsletter — only if requested by user
    if do_newsletter_signup:
        signup_newsletter(user_account)
    # send confirmation mail
    send_confirmation_mail(user_account)

Dis­tin­guer deux cas distincts avec l’ins­truc­tion if-else en Python

Souvent, les pro­grammes doivent dis­tin­guer deux cas qui s’excluent mu­tuel­le­ment. S’il est lo­gi­que­ment évident qu’il ne peut pas y avoir d’autres cas, il est judicieux d’utiliser une ins­truc­tion if-else. A titre d’exemple, nous testons si une personne a atteint un certain âge et affichons à chaque fois un résultat approprié :

def is_of_age(person, age_limit = 18):
    if person.age >= age_limit:
        print("You're old enough")
    else:
        print("Sorry, wait some more")

Dis­tin­guer plusieurs cas exclusifs avec les ins­truc­tions elif en Python

S’il y a plus de deux cas mu­tuel­le­ment exclusifs que nous voulons dis­tin­guer, nous utilisons des ins­truc­tions elif en­chaî­nées. Un else final sert à attraper la variante inconnue. Nous at­tri­buons les noms de pays aux codes de pays cor­res­pon­dants :

def get_country_from_code(country_code):
    if country_code == 'DE':
        country = "Deutschland"
    elif country_code == 'ES':
        country = "España"
    elif country_code == 'FR':
        country = "France"
    elif country_code == 'GB':
        country = "Great Britain"
    elif country_code == 'IT':
        country = "Italia"
    else:
        country = None
    return country

Dans la mesure où la chaîne elif se trouve à l’intérieur d’une fonction, il est parfois pré­fé­rable d’utiliser plusieurs ins­truc­tions if in­dé­pen­dantes. Ainsi, nous évitons l’af­fec­ta­tion dans le corps elif. L’ins­truc­tion return permet de quitter la fonction si l’une des con­di­tions est remplie. Au lieu du else final, on utilise une ins­truc­tion return placée en dernier, qui n’est atteinte que si aucune des con­di­tions n’est True :

def get_country_from_code(country_code):
    if country_code == 'DE':
        return "Deutschland"
    if country_code == 'ES':
        return "España"
    if country_code == 'FR':
        return "France"
    if country_code == 'GB':
        return "Great Britain"
    if country_code == 'IT':
        return "Italia"
    return None

Les ins­truc­tions elif en­chaî­nées sont un modèle bien connu des anciens langages. En Python, il est souvent plus direct d’utiliser un « Dic­tio­nary Lookup ». Nous dé­fi­nis­sons di­rec­te­ment la cor­res­pon­dance entre les codes et les noms de pays et nous extrayons le nom à partir du code. Au lieu du else final, nous utilisons la méthode get intégrée, qui prend une valeur par défaut comme deuxième paramètre :

def get_country_from_code(country_code):
    countries = {
        'DE': "Deutschland",
        'ES': "España",
        'FR': "France",
        'GB': "Great Britain",
        'IT': "Italia",
    }
    country = countries.get(country_code, None)
    return country

Vérifier si un objet contient des données avec l’ins­truc­tion if en Python

Python est un langage à typage dynamique. Au lieu d’être liés à des variables, les types sont liés à des valeurs. Selon l’uti­li­sa­tion, des con­ver­sions im­pli­cites entre types peuvent avoir lieu. Dans le contexte des ex­pres­sions boo­léennes, on parle également de « truthy » et de « falsy » par extension des valeurs de vérité True et False.

Cela signifie que la condition d’une ins­truc­tion if en Python n’a pas besoin d’être ex­pli­ci­te­ment évaluée en True ou False. Au contraire, des valeurs d’autres types peuvent être utilisées comme condition. Celles-ci sont in­ter­pré­tées comme des valeurs boo­léennes selon certaines règles.

Citation

„Any object can be tested for truth value, for use in an if or while condition or as operand of the Boolean ope­ra­tions […]

[...] An object is con­si­de­red true unless its class defines either a __bool__() method that returns False or a __len__() method that returns zero [...]“ – Source : https://docs.python.org/3/library/stdtypes.html#truth-value-testing

Tra­duc­tion : « Tout objet peut être comparé à une valeur booléenne, ty­pi­que­ment dans une condition if ou while ou comme opérande des opé­ra­tions boo­léennes [...]

[...] tout objet est considéré vrai à moins que sa classe définisse soit une méthode __bool__() renvoyant False soit une méthode __len__() renvoyant zéro [...] » (tra­duc­tion de IONOS)

Nous utilisons ce modèle pour vérifier si un objet contient des données. Comme le texte suivant est vide, un message cor­res­pon­dant est affiché :

text = ''
if not text:
    print("No text given")

Les objets suivants sont évalués comme False dans un contexte booléen et sont donc appelés « falsy » :

Objet Ex­pli­ca­tion
False, None Cons­tantes qui, par dé­fi­ni­tion, sont fausses
0, 0.0, Decimal(0), Fraction(0, 1), etc. Nombre re­pré­sen­tant zéro
'', (), [], {}, set(), range(0), etc. Séquence ou col­lec­tion vide

Un autre exemple avec une liste vide :

books_in_library = []
if not books_in_library:
    print("Library is empty")

Tous les autres objets sont évalués comme True :

number = 42
if number:
    print("Number exists")

Im­plé­men­ter un in­ter­rup­teur binaire avec if-else en Python

Une ins­truc­tion if-else en Python est également utilisée pour passer d’un état à l’autre de manière exclusive. Le principe ressemble à un in­ter­rup­teur de lumière et est appelé « toggle » en anglais. Nous dé­fi­nis­sons une fonction qui inverse l’état d’une lumière :

def toggle_light(light):
    if light == 'on':
        return 'off'
    else:
        return 'on'

Vous le voyez peut-être déjà : c’est encore plus simple. Si l’état n’est pas re­pré­senté par une chaîne de ca­rac­tères, mais par une valeur booléenne, il est possible de renoncer com­plè­te­ment à l’ins­truc­tion if. Au lieu de cela, nous utilisons l’opérateur logique NON pour inverser la valeur booléenne :

def toggle(boolean):
    return not boolean

Résoudre des ins­truc­tions if im­bri­quées avec Early Return en Python

Dans la pratique, il est courant d’exécuter certains codes lorsque plusieurs con­di­tions sont vraies en même temps. Pour les pro­gram­meurs inex­pé­ri­men­tés, cela conduit ra­pi­de­ment à des ins­truc­tions if im­bri­quées. Il s’agit toutefois d’un mauvais style. En effet, il est difficile d’avoir une vue d’ensemble des ra­mi­fi­ca­tions pro­fon­dé­ment im­bri­quées et de les en­tre­te­nir.

Prenons un exemple : nous écrivons une fonction qui indique si une personne peut voter. Nous vérifions d’abord si la personne possède une pièce d’identité. Ensuite, nous vérifions si la personne a déjà atteint l’âge de voter. Une première im­plé­men­ta­tion de la fonction contient des ins­truc­tions if im­bri­quées :

def person_may_vote(person, voting_age = 18):
    if person.has_id():
        if person.get_age() >= voting_age:
            return True

Un problème immédiat de cette im­plé­men­ta­tion est que plus les con­di­tions sont testées, plus le code le plus important est décalé. Pour résoudre les ins­truc­tions if im­bri­quées, nous utilisons la meilleure pratique du « Early Return ». Nous vérifions au début de la fonction si les dif­fé­rentes con­di­tions sont remplies. Si une condition n’est pas remplie, nous nous arrêtons et quittons la fonction en utilisant l’ins­truc­tion return.

Nous re­for­mu­lons notre fonction pour utiliser Early Return. Souvent, cela nécessite d’inverser les con­di­tions définies pré­cé­dem­ment. Pour cela, il est utile de com­prendre les opé­ra­teurs booléens de Python. Si aucune des con­di­tions négatives ne s’applique, le code pertinent est exécuté :

def person_may_vote(person, voting_age = 18):
    if not person.has_id():
        return False
    if person.age < voting_age:
        return False
    # if we made it here, the person may vote
    return True

Sim­pli­fier et remplacer les ins­truc­tions if en Python à l’aide d’opé­ra­teurs logiques

Comme nous l’avons déjà vu, il est souvent né­ces­saire de tester la réa­li­sa­tion de plusieurs con­di­tions. La plupart du temps, il n’est pas optimal d’utiliser des ins­truc­tions if im­bri­quées pour tester plusieurs con­di­tions. Prenons l’exemple d’un code qui détermine si une personne peut voter :

if has_id(person):
    if is_adult(person):
        print("You may vote")

La condition enchaînée peut être mieux re­pré­sen­tée en utilisant des opé­ra­teurs logiques. Comme nous voulons tester si les deux con­di­tions s’ap­pli­quent si­mul­ta­né­ment, nous utilisons l’opérateur logique ET. Ainsi, nous n’avons besoin que d’une seule ins­truc­tion if :

if has_id(person) and is_adult(person):
    print("You may vote")

Voici un aperçu des opé­ra­teurs logiques de base en Python :

Opérateur logique Sig­ni­fi­ca­tion Syntaxe Python Autre langage
ET L’ex­pres­sion est vraie si tous les opérandes sont vrais ; renvoie le dernier opérande évalué. and &&
OU L’ex­pres­sion est vraie si au moins un des opérandes est vrai ; renvoie le dernier opérande évalué. or
NON Inverse la valeur de l’ex­pres­sion. not !

En plus de la liaison d’opérandes dans des con­di­tions, les opé­ra­teurs logiques sont utilisés pour remplacer certaines ins­truc­tions if. Il s’agit en l’oc­cur­rence de définir des valeurs par défaut.

Prenons un exemple : imaginons qu’un uti­li­sa­teur puisse définir une devise pour un calcul financier. Pour des raisons de con­vi­via­lité, ce choix doit être fa­cul­ta­tif. Si l’uti­li­sa­teur ne choisit pas de devise, EUR doit être utilisé comme valeur par défaut. Le code suivant illustre ce principe :

# user made no currency choice
currency = None
...
# further down in the program flow
if not currency:
    # set default if value missing
    currency = 'EUR'

En utilisant l’opérateur logique OU, l’ins­truc­tion if peut être résolue. Nous réé­cri­vons le code ; lorsqu’il est exécuté, la variable « currency » contient la valeur 'EUR' :

# user made no currency choice
currency = None
...
# further down in the program flow
# set default if value missing
currency = currency or 'EUR'

Que se passe-t-il ici exac­te­ment ? Dans la dernière ligne, une nouvelle valeur est attribuée à la variable 'cur­ren­cy'. Pour ce faire, l’ex­pres­sion 'currency or 'EUR' est d’abord évaluée à droite du signe égal. L’opérateur logique OU évalue d’abord l’ex­pres­sion de gauche, dans ce cas 'cur­ren­cy'. Comme celle-ci contient 'None' dans l’exemple et est donc 'falsy', l’ex­pres­sion de droite 'EUR' est évaluée et utilisée comme valeur de retour pour l’af­fec­ta­tion.

L’opérateur con­di­tion­nel if-else en Python

En plus du bran­che­ment con­di­tion­nel, les mots clés if-else en Python ont une autre utilité. Il s’agit de l’opérateur con­di­tion­nel, également connu sous le nom d’opérateur « ternaire ». L’opérateur con­di­tion­nel est vo­lon­tiers utilisé pour faire la dis­tinc­tion entre deux valeurs possibles dans les af­fec­ta­tions.

Con­si­dé­rons d’abord un exemple utilisant l’ins­truc­tion if-else en Python. Le code suivant définit Celsius ou Fah­ren­heit comme unité pour une mesure de tem­pé­ra­ture en fonction du système de mesure choisi :

if system == 'metric':
    unit = 'C'
else:
    unit = 'F'

En utilisant l’opérateur con­di­tion­nel, le code peut être simplifié en une seule ins­truc­tion :

unit = 'C' if system == 'metric' else 'F'

Comme son nom l’indique, l’opérateur ternaire prend trois opérandes : les deux valeurs possibles et une ex­pres­sion comme condition.

Arité de l’opérateur Ex­pli­ca­tion Exemple
Unaire L’opérateur accepte un opérande. not boolean_operand
Binaire L’opérateur accepte deux opérandes. left_operand + right_operand
Ternaire L’opérateur accepte trois opérandes. some_value if condition else other_value

Remplacer if-else dans Python avec l’ins­truc­tion match-case

L’ins­truc­tion match-case a été in­tro­duite avec la sortie de la version 3.10 de Python. Celle-ci rappelle l’ins­truc­tion switch-case d’autres langages. Dans ce cas, switch-case est utilisé pour briser les grandes cons­truc­tions if-elif-else.

Réputé pour être sujet aux erreurs, switch-case n’a jamais existé en Python. L’ins­truc­tion match-case en Python est plutôt une fonc­tion­na­lité de « Struc­tu­ral Pattern Matching » inspirée des langages fonc­tion­nels comme Haskell. Son utilité va bien au-delà de celle de switch-case.

Il­lus­trons le principe de match-case par un exemple : imaginons que nous voulions traiter des données de personnes dans dif­fé­rents formats. Une personne peut être re­pré­sen­tée soit sous la forme d’un nom unique, soit sous la forme d’un dic­tion­naire avec le nom et éven­tuel­le­ment l’âge, soit sous la forme d’un tuple de prénoms et de noms. Nous sou­hai­tons également traiter le nom exact « Jack » de manière par­ti­cu­lière :

# the name 'Jack'
person1 = 'Jack'
# just a name
person2 = 'John'
# name and age in a dict
person3 = {'name': 'Jim', 'age': 42}
# name in a dict, but no age
person4 = {'name': 'Walter', 'email': 'walter.white@example.com'}
# tuple of first and last name
person5 = ('Walther', 'White')

Regardons d’abord une fonction qui accueille une personne dans l’un des formats. Nous utilisons une chaîne if-elif-else et la fonction isins­tance pour dis­tin­guer les dif­fé­rents formats. Nous utilisons également des con­di­tions en­chaî­nées avec l’opérateur ET et une ins­truc­tion if-else imbriquée. Le code final n’est pas très explicite :

def greet_person(person):
    if isinstance(person, str):
        if person == 'Jack':
            print('Jack himself has arrived')
        else:
            print(f"Hi there, {person}")
    elif isinstance(person, dict) and 'name' in person and 'age' in person:
        print(f"It's, {person['name']}. Born {person['age']} years ago")
    elif isinstance(person, dict) and 'name' in person:
        print(f"It's {person['name']}")
    elif isinstance(person, tuple) and len(person) == 2:
        first, last = person
        print(f"Hello, {first} {last}")
    else:
        print('Not sure what kind of person this is')

Le code peut être construit plus joliment avec l’ins­truc­tion match-case. Nous décrivons di­rec­te­ment la structure des dif­fé­rents formats ; les valeurs in­di­vi­duelles peuvent être extraites en tant que variables. Le code est plus clair, moins complexe et plus lisible :

def match_person(person):
    match person:
        case 'Jack':
            print('Jack himself has arrived')
        case str() as name:
            print(f"Hi there, {name}")
        case {'name': name, 'age': age}:
            print(f"It's, {name}. Born {age} years ago")
        case {'name': name}:
            print(f"It's {name}")
        case (first, last):
            print(f"Hello, {first} {last}")
        case _:
            print('Not sure what kind of person this is')
Aller au menu principal