Conditions et boucles
Ce que ce chapitre apporte 7 points
- Prendre une décision avec if, elif et else.
- Comprendre pourquoi une suite de if ne fait pas la même chose qu'un elif.
- Répéter avec for et avec while, et savoir lequel choisir.
- Choisir une valeur en une ligne avec a if condition else b.
- Écrire un encadrement 0 <= x < 10 d'un seul tenant, et tester l'absence de valeur par is None.
- Redemander une saisie tant qu'elle est invalide, en interceptant l'erreur avec try / except.
- Éviter les trois pièges classiques : = au lieu de ==, or mal écrit, boucle infinie.
Jusqu'ici, les programmes se lisaient de haut en bas, ligne après ligne, toujours dans le même ordre. Ce chapitre change cela : le programme va se mettre à décider et à répéter.
Ces deux structures ne dépendent d'aucun langage, et le parcours d'algorithmique les traite pour elles-mêmes : les conditions et les tests logiques, avec la branche jamais atteinte et la négation d'une conjonction, puis les boucles et les répétitions, avec le compte exact des tours.
On a déjà vu ces idées en algorithmique, sous la forme « Si / Alors / Sinon » et « Tant que ». Python reprend exactement la même logique. C'est le chapitre le plus important du cours : ces deux mécanismes sont dans absolument tous les programmes qu'on écrira.
La première décision
Un programme qui décide, cela ressemble à ceci. Exécuter, puis change la valeur de age.
Deux lignes s'affichent seulement quand la condition est vraie, une troisième s'affiche toujours. Regardons bien pourquoi : les deux premières sont décalées vers la droite, la dernière non.
L'indentation, la règle d'or
L'indentation est le décalage d'une ligne vers la droite. En Python, elle n'est pas décorative : c'est elle, et elle seule, qui dit quelles lignes appartiennent au bloc.
Là où d'autres langages emploient des accolades, Python emploie l'espace. La convention est de quatre espaces par niveau. Ce qui est décalé sous le if ne s'exécute que si la condition est vraie ; ce qui revient à gauche s'exécute dans tous les cas.
À faire. Dans le bloc précédent, décale print("Fin du programme.") de quatre espaces vers la droite, mets age = 15, et relance. La ligne ne s'affiche plus : elle est devenue une ligne du if.
Le bloc suivant est faux exprès : l'indentation manque.
IndentationError: expected an indented block. Traduction : Python a lu les deux points, il attend donc un bloc décalé, et il n'en trouve pas.
Choisir entre plusieurs cas
else couvre tout ce que le if n'a pas pris. elif, contraction de « else if », ajoute un cas intermédiaire.
Python teste dans l'ordre et s'arrête à la première condition vraie. Les suivantes ne sont même pas évaluées.
if ne fait pas la même chose qu'un elifExécutons ce bloc, qui attribue une mention à une note de 15.
Deux lignes s'affichent. Les trois if sont indépendants : chacun est évalué, et les deux premiers sont vrais. Ce n'est pas ce qu'on voulait.
À faire. Remplacer les deuxième et troisième if par des elif, puis inverse l'ordre en mettant note >= 16 en premier. Relance : une seule mention s'affiche, la bonne. Avec elif, l'ordre décide de tout.
Comparer
| Opérateur | Sens | Exemple | Résultat |
|---|---|---|---|
== | égal à | 5 == 5 | True |
!= | différent de | 3 != 4 | True |
< <= | inférieur, inférieur ou égal | 3 <= 3 | True |
> >= | supérieur, supérieur ou égal | 8 >= 9 | False |
Un test renvoie toujours un booléen, True ou False. On peut l'afficher directement, c'est un bon moyen de vérifier une condition compliquée avant de la mettre dans un if.
Le bloc suivant est faux exprès : il confond affectation et comparaison.
SyntaxError: invalid syntax. Rappel du chapitre 2 : = colle une étiquette, c'est une action. == compare, c'est une question. Dans un if, on pose une question.
Deux écritures reviennent sans cesse dans le code d'ingénieur, et elles méritent d'être connues dès maintenant.
La première est l'encadrement. Pour vérifier qu'une température est dans une plage, les mathématiques écrivent 18 ≤ t < 25, et Python accepte exactement la même chose : 18 <= t < 25. Il la lit comme 18 <= t and t < 25, en ne calculant t qu'une fois. C'est plus court, et surtout plus proche de ce qu'on a en tête.
La seconde est le test d'absence de valeur. Python possède une valeur spéciale, None, qui signifie « rien » : un capteur qui n'a encore rien envoyé, une recherche qui n'a rien trouvé. Le chapitre suivant la rencontrera souvent. Pour savoir si une variable vaut None, on écrit mesure is None, et non mesure == None. is demande « est-ce le même objet ? », et il n'existe qu'un seul None : la question est donc exacte, là où == peut être détourné par certains objets, comme ceux de NumPy qu'on verra plus tard. La règle est simple : is pour None, == pour tout le reste.
Combiner plusieurs conditions
and exige que les deux soient vraies, or qu'au moins une le soit, not inverse.
if choix == 1 or 2:, et cette condition est toujours vraie, quelle que soit la valeur de choix.Python lit en effet
(choix == 1) or (2). Or le nombre 2 n'est pas nul, donc il est tenu pour vrai, comme on l'a vu au chapitre 2 : seul zéro est faux. Un or dont un côté est toujours vrai est toujours vrai.Il faut répéter la variable de chaque côté :
if choix == 1 or choix == 2:
Le vérifier soi-même : le premier test devrait être faux, et pourtant.
La première ligne n'affiche pas True mais 2, et c'est une seconde surprise : or ne rend pas un booléen, il rend la valeur qui a tranché. Ici choix == 1 est faux, alors Python regarde à droite et rend 2 tel quel. Le if, lui, ne pose à cette valeur qu'une seule question, est-elle vraie, et 2 l'est : c'est ce que montre la deuxième ligne.
Il existe une écriture plus courte et plus sûre, qu'on peut employer dès maintenant : if choix in (1, 2):. Le mot in demande si la valeur figure parmi celles qu'on énumère entre parenthèses ; cette suite de valeurs entre parenthèses s'appelle un tuple, et le chapitre suivant lui donne sa place.
Choisir une valeur en une ligne
Il arrive souvent qu'un if / else ne serve qu'à donner une valeur à une seule variable, selon une condition. Python propose pour ce cas une écriture en une ligne, l'expression conditionnelle : valeur_si_vrai if condition else valeur_si_faux. Elle se lit presque comme une phrase : « surtension si la tension dépasse 13,5 V, sinon normal ».
Elle est réservée aux choix simples entre deux valeurs. Dès qu'il y a trois cas, ou des instructions à exécuter plutôt qu'une valeur à produire, le if / elif / else sur plusieurs lignes reste plus lisible.
Répéter un nombre connu de fois : for
La boucle for répète un bloc pour chaque élément d'une suite de valeurs. On l'emploie quand on sait, avant de commencer, sur quoi on va boucler.
La variable i n'est pas la boucle : c'est une étiquette que Python décolle et recolle sur une nouvelle valeur à chaque tour, exactement comme au chapitre 2. Après la boucle, elle garde la dernière valeur prise.
Le mot pass ne fait rien, et c'est son rôle : Python exige au moins une ligne dans un bloc décalé, et pass tient la place quand on n'a encore rien à y mettre.
On boucle aussi directement sur une suite de valeurs, sans passer par des numéros.
Les crochets créent une liste, une suite de valeurs rangées dans l'ordre. Le chapitre suivant lui est entièrement consacré ; ici, il suffit de savoir que for la parcourt du premier au dernier élément.
range(), et sa borne qui surprend
range(debut, fin, pas) engendre des entiers : debut inclus, fin exclue, pas valant 1 par défaut.
range(1, 10) ne contient pas 10. C'est déroutant au début, et parfaitement régulier : le nombre de valeurs vaut exactement fin - debut, ce qui évite une addition mentale à chaque usage.Pour aller jusqu'à 10 inclus, il faut écrire
range(1, 11). Enveloppe un range dans list() quand on doute : on verra les valeurs.
L'accumulateur est le motif le plus employé de toute la programmation, et le plus difficile à voir pour qui débute : la variable total change à chaque tour, et rien sur la page ne le montre. La figure ci-dessous le déroule.
| 1 | total = 0 |
| 2 | for n in [3, 7, 2]: |
| 3 | total = total + n |
| 4 | print(total) |
Variables
| total | 0 |
Trois choses se lisent sur cette trace, et aucune ne se déduit du code seul.
total = 0 s'exécute une seule fois, avant la boucle. Le placer à l'intérieur remettrait le compteur à zéro à chaque tour, et c'est l'erreur la plus fréquente sur ce motif.
La ligne for revient à chaque tour : c'est elle qui donne à n sa valeur suivante. La boucle n'est pas un bloc qu'on exécute trois fois d'affilée, c'est un aller-retour entre l'en-tête et le corps.
Enfin, n existe encore après la boucle et vaut 2, la dernière valeur prise. Python ne l'efface pas en sortant.
1.Que produit range(1, 5) ?
2.Avec note = 15, combien de lignes affiche une suite de trois if indépendants dont les conditions sont >= 10, >= 14 et >= 16 ?
Quand l'indice sert vraiment : enumerate
Parcourir une liste se fait directement, for note in notes. Mais il arrive qu'on ait besoin du rang en même temps que de la valeur : afficher un classement, signaler la ligne fautive d'un fichier, retrouver une position.
La tentation est alors d'écrire for i in range(len(notes)) et d'aller chercher notes[i], où len(notes) donne le nombre d'éléments de la liste et notes[i] l'élément de rang i, le premier ayant le rang 0. Cela fonctionne, et cela fait deux choses là où une suffirait.
enumerate rend à chaque tour un couple, que la boucle dépaquette en deux noms. C'est le tuple du chapitre suivant, employé ici sans qu'on ait à le nommer.
Parcourir deux listes de front : zip
L'autre besoin fréquent est d'avancer dans deux listes en même temps, un nom et sa note, une date et sa mesure.
zip s'arrête dès que l'une est épuisée, et les éléments restants de l'autre sont ignorés sans le moindre message. Un relevé tronqué se traduit donc par des lignes manquantes, pas par une alerte.Quand les deux listes doivent avoir la même longueur, le vérifier explicitement avant :
assert len(a) == len(b), ou un if qui refuse le traitement.
Le signe que deux listes parallèles étaient une mauvaise idée.
zip répare une situation, il ne la rend pas saine. Deux listes qu'on parcourt toujours ensemble décrivent en réalité un seul objet à deux propriétés, et un tri sur l'une les désynchronise définitivement.
Le chapitre suivant donne la forme correcte, le dictionnaire, puis la liste de dictionnaires. zip reste utile pour rapprocher deux séries qui viennent vraiment de sources différentes.
zip sur une liste de 4 éléments et une de 2 produit combien de tours ?
Répéter tant qu'une condition tient : while
La boucle while répète un bloc tant que sa condition est vraie. On l'emploie quand on ne sait pas d'avance combien de tours seront nécessaires.
Lequel choisir : une seule question.
Est-ce que je sais, avant de commencer, sur quoi je boucle ?
Oui, une liste, un nombre de tours, un fichier : c'est un for.
Non, cela dépend de ce qui se passera pendant : c'est un while. Attendre une saisie correcte, jouer jusqu'à ce qu'un joueur gagne, lire jusqu'à la fin d'un flux.
Les débutants écrivent souvent un while avec un compteur qu'ils incrémentent à la main, là où un for tenait en une ligne. Si on écrit compteur += 1 à la fin du while, se demander si un for ne ferait pas l'affaire.
Un while a besoin de trois choses, et en oublier une est l'erreur classique : initialiser la variable avant, la tester dans la condition, et la faire évoluer dans le bloc.
Le bloc suivant est faux exprès : la troisième manque.
Rien ne fait grandir compteur, la condition reste vraie pour toujours. Au bout de quelques secondes, la plateforme interrompt l'exécution et affiche un message de dépassement de temps. Sur la machine, il faudrait interrompre le programme à la main.
À faire. Ajouter compteur += 1 dans le bloc, puis relancer.
Le while demande une vigilance que le for n'exige pas : c'est au programmeur de faire progresser la condition vers sa fin. Dérouler la trace montre exactement ce qui rapproche du terme.
| 1 | n = 5 |
| 2 | resultat = 1 |
| 3 | while n > 1: |
| 4 | resultat = resultat * n |
| 5 | n = n - 1 |
| 6 | print(resultat) |
Variables
| n | 5 |
La ligne while est réévaluée à chaque tour, y compris la dernière fois où elle est fausse et fait sortir. La ligne n = n - 1 est la seule qui rapproche de cette sortie : la retirer donnerait une boucle sans fin, et le programme ne s'arrêterait jamais de lui-même.
1.if choix == 1 or 2: avec choix = 9. Que se passe-t-il ?
2.Quand faut-il un while plutôt qu'un for ?
break et continue
| Instruction | Effet |
|---|---|
break | sort de la boucle immédiatement |
continue | passe au tour suivant sans finir celui-ci |
Que vaut i juste après for i in range(3): pass ?
Redemander tant que la saisie est invalide
Plus haut, on a rangé « attendre une saisie correcte » parmi les usages du while. Voici le cas concret : le programme demande un nombre de mesures, et l'utilisateur tape douze en toutes lettres. Au chapitre 2, on a vu que int() ne sait pas convertir ce texte.
ValueError: invalid literal for int() with base 10: 'douze', et la dernière ligne ne s'exécute pas.
Une exception est une erreur qui survient pendant l'exécution. Python arrête alors le programme et affiche le nom de l'erreur, suivi d'une explication : ValueError pour une valeur qui ne convient pas, ZeroDivisionError pour une division par zéro, IndexError ou KeyError pour un élément qui n'existe pas, qu'on verra au chapitre suivant.
Une exception n'est pas forcément la fin du programme : on peut l'intercepter. Le bloc try contient les lignes qui risquent d'échouer ; le bloc except ValueError contient ce qu'il faut faire si et seulement si une ValueError survient dans le try. Si tout se passe bien, le bloc except est simplement sauté.
Combiné à une boucle, cela donne le motif qu'on retrouve dans tout programme qui dialogue avec un utilisateur : while True répète sans condition, et break en sort dès que la saisie est valide. Sur la machine, chaque saisie viendrait de input("Nombre de mesures : "). Ici, pour que le bloc s'exécute d'un coup, une liste simule trois saisies successives, et saisies.pop(0) retire et rend la première de la liste à chaque tour.
Les deux premières saisies échouent, et le break n'est jamais atteint : l'exception saute directement dans le except, qui affiche un message, puis la boucle recommence. À la troisième, int() réussit, le break s'exécute et le programme continue avec un n qui est forcément un entier. while True n'est pas une boucle infinie ici, parce que le break en est la sortie.
except: tout seulexcept: sans nom d'erreur intercepte toutes les exceptions, y compris celles qu'on n'avait pas prévues. Une faute de frappe dans un nom de variable, une division par zéro plus bas dans le try : tout passe pour « saisie invalide », et le programme redemande en boucle sans jamais montrer le vrai problème.Nommer l'erreur attendue,
except ValueError:, c'est dire exactement ce qu'on sait réparer. Les autres erreurs continuent d'arrêter le programme avec leur message, et c'est ce qu'on veut : un bug doit se voir.
1.Que se passe-t-il quand int("douze") s'exécute en dehors de tout try ?
2.Pourquoi écrire except ValueError: plutôt que except: tout seul ?
Boucles imbriquées
Une boucle peut en contenir une autre. La boucle intérieure se déroule entièrement à chaque tour de la boucle extérieure.
Trois tours extérieurs, deux tours intérieurs à chaque fois : six lignes. C'est le schéma qui sert à parcourir un tableau à deux dimensions.
Le mot entièrement est celui qui résiste. La trace le montre sans commentaire : j fait tout son parcours avant que i ne bouge d'un cran, et il repart de zéro à chaque fois.
| 1 | total = 0 |
| 2 | for i in range(3): |
| 3 | for j in range(2): |
| 4 | total = total + 1 |
| 5 | print(i, j, total) |
Variables
| total | 0 |
j : il monte de 0 à 1, puis redescend brutalement à 0. Regarder alors i à cet instant précis : c'est exactement là qu'il avance d'un cran. Le compteur total dit le reste : six tours intérieurs pour trois tours extérieurs, c'est-à-dire le produit et non la somme. Une boucle de mille dans une boucle de mille fait un million de tours, et c'est pourquoi une imbrication de trop se paie si cher.
Mettre en pratique
FizzBuzz. Afficher les nombres de 1 à 20, en remplaçant les multiples de 3 par Fizz, les multiples de 5 par Buzz, et les multiples de 3 et de 5 par FizzBuzz.
Afficher la solution
L'ordre est ce qui compte. Le cas « multiple de 3 et de 5 » vient en premier : mis en dernier, il ne serait jamais atteint, puisqu'un multiple de 15 est déjà un multiple de 3 et sortirait sur le premier elif.
C'est exactement le piège de la section sur elif : avec une suite d'elif, le premier vrai gagne, donc le cas le plus restrictif se place en tête.
Chapitre révisé en octobre 2026 · Une erreur dans ce chapitre ?
Dans la bibliothèque d'exercices
if, elif, else et opérateurs de comparaison.
- Suivre un aiguillage1 · Débuter
- Un elif, puis deux if1 · Débuter
- Débogage : un code qui passe toujours2 · Fonctions
- La charge maximale d'un palan2 · Fonctions
- Une trame sur deux2 · Fonctions
- Les seuils d'une baie de batteries2 · Fonctions
- Une saisie d'humidité à contrôler3 · Confirmé
- Le niveau de vigilance vent3 · Confirmé
for, while, accumulation et compteurs.
- Suivre une accumulation1 · Débuter
- Suivre une boucle while2 · Fonctions
- Débogage : le cumul oublie un jour2 · Fonctions
- Une table de conversion1 · Débuter
- S'arrêter au bon moment1 · Débuter
- Des relevés manquants3 · Confirmé
- Le plan des emplacements d'un magasin2 · Fonctions
- La plus longue période de gel3 · Confirmé
Passer du pseudo-code au Python, ligne à ligne : Lire, Si, Pour et TantQue.
- Traduire une séquence1 · Débuter
- Traduire une lecture et un calcul1 · Débuter
- Traduire une condition2 · Fonctions
- Traduire trois cas2 · Fonctions
- Traduire une boucle Pour2 · Fonctions
- Traduire un accumulateur3 · Confirmé
- Traduire une boucle TantQue3 · Confirmé
Remettre les lignes d'un programme dans l'ordre : avant, dans et après la boucle.
- Un message en trois temps1 · Débuter
- Surtension ou normal2 · Fonctions
- La somme de 1 à n2 · Fonctions
- Redemander jusqu'à une saisie valide3 · Confirmé