# Boucles et conditions en Python : for, while, range, enumerate, break, if/elif et match/case

URL: https://skillaria.top/fr/guides/python/boucles-python

Les boucles en Python répètent une action : for parcourt les éléments de n'importe quelle collection ou d'un range(), while s'exécute tant que la condition est vraie. break interrompt la boucle, continue passe à l'itération suivante, enumerate() fournit le numéro de l'élément. Les décisions se prennent avec if/elif/else, et le tri des données selon leur forme avec match/case (depuis Python 3.10).

Les boucles en Python servent à répéter une action : parcourir une liste de courses, traiter chaque ligne d'un fichier, redemander un nombre tant que l'utilisateur n'en saisit pas un correct. Le langage propose deux boucles, `for` et `while`, et les conditions `if/elif/else` ainsi que l'instruction `match/case` permettent de prendre des décisions à l'intérieur. Passons en revue chaque outil à l'aide d'exemples concrets.

## Conditions : if, elif, else

L'instruction conditionnelle exécute un bloc de code seulement si l'expression est vraie. Le bloc est délimité par un retrait de 4 espaces : Python n'utilise pas d'accolades, et un retrait incorrect provoque immédiatement l'erreur `IndentationError`.

```
depense = 4200
limite = 5000

if depense > limite:
    print("Le plafond est dépassé")
elif depense > limite * 0.8:
    print("Il reste moins de 20 % du budget")
else:
    print("Tout va bien")
```

Les branches `elif` sont évaluées de haut en bas, et une seule s'exécute : la première qui correspond. Placez donc les conditions les plus strictes en premier : si la vérification `depense > limite * 0.8` venait avant, le message de dépassement du plafond n'apparaîtrait jamais.

### Ce qui est considéré comme vrai

Dans une condition, il n'est pas obligatoire d'écrire une comparaison. Sont considérés comme faux : `False`, `None`, zéro (`0`, `0.0`) et les collections vides : `""`, `[]`, `{}`. Tout le reste est vrai. La vérification « la liste n'est pas vide » s'écrit donc brièvement :

```
depenses = []
if not depenses:
    print("Pas encore de dépenses")
```

On combine les conditions avec `and`, `or` et `not`, et un intervalle se vérifie plus lisiblement par une chaîne de comparaisons : `if 0 < montant <= 100_000:`. Pour un choix simple, il existe l'opérateur ternaire : `statut = "élevé" if depense > limite else "normal"`.

## La boucle for en Python : syntaxe et exemples

La boucle `for` de Python n'est pas un compteur, comme en C : elle parcourt les éléments un à un. Elle prend chaque élément d'un objet itérable (liste, chaîne, dictionnaire, fichier, intervalle). C'est l'équivalent du foreach d'autres langages.

```
depenses = [350, 1200, 89, 4500]
total = 0
for montant in depenses:
    total += montant
print(total)  # 6139
```

Syntaxe : `for variable in collection:`, suivi d'un bloc avec retrait. Après la boucle, la variable conserve la dernière valeur : cela peut être utile, mais il vaut mieux ne pas s'y fier dans les gros programmes.

### Boucle sur une chaîne, une liste et un dictionnaire

Une chaîne est parcourue caractère par caractère, une liste élément par élément. Une boucle sur un dictionnaire porte par défaut sur les clés ; pour obtenir à la fois la clé et la valeur, utilisez `.items()` :

```
par_categorie = {"alimentation": 3200, "transport": 900, "cinéma": 600}

for categorie, montant in par_categorie.items():
    print(f"{categorie} : {montant} €")
```

Pour les seules valeurs, utilisez `.values()`. Il est interdit de modifier la taille d'un dictionnaire pendant le parcours : vous obtiendrez `RuntimeError: dictionary changed size during iteration`. Si vous devez supprimer des éléments, parcourez une copie : `for cle in list(d):`.

## La fonction range : boucler sur des nombres

Pour parcourir des nombres, on utilise `range()`. Elle ne crée pas de liste en mémoire, mais fournit les nombres un par un : `range(10**9)` démarre donc instantanément.

| Appel | Nombres |
| --- | --- |

| `range(5)` | 0, 1, 2, 3, 4 |

| `range(2, 6)` | 2, 3, 4, 5 |

| `range(0, 10, 3)` | 0, 3, 6, 9 |

| `range(5, 0, -1)` | 5, 4, 3, 2, 1 |

Règle essentielle : la borne droite n'est jamais incluse. `range(1, 10)` s'arrête à 9 — c'est une cause fréquente d'erreur « d'un cran ». Le pas peut être négatif, mais pas nul.

```
for i in range(1, 4):
    print(f"Jour {i}")
# Jour 1
# Jour 2
# Jour 3
```

## enumerate : un compteur dans la boucle

Les débutants écrivent souvent `for i in range(len(items))` pour connaître le numéro de l'élément. Cela fonctionne, mais se lit mal. La fonction `enumerate()` renvoie des paires « numéro, élément », et le paramètre `start` indique à partir de quel nombre compter :

```
articles = ["café", "taxi", "déjeuner"]
for n, article in enumerate(articles, start=1):
    print(n, article)
# 1 café
# 2 taxi
# 3 déjeuner
```

Pour parcourir deux listes en parallèle, utilisez `zip()` : `for nom, prix in zip(noms, prix):`. Elle s'arrête à la plus courte des deux listes ; à partir de Python 3.10, on peut passer `strict=True`, et une longueur différente déclenche alors une erreur.

## La boucle while en Python

La boucle `while` répète le bloc tant que la condition est vraie. On la choisit quand le nombre de répétitions n'est pas connu à l'avance : attendre une saisie correcte, lire des données jusqu'à la fin, relancer une requête jusqu'à ce qu'elle réussisse.

```
solde = 10_000
mois = 0
while solde > 0:
    solde -= 2_700
    mois += 1
print(f"L'argent suffit pour {mois} mois")  # 4
```

Le piège principal est d'oublier de modifier la variable qui figure dans la condition : la boucle ne se termine alors jamais. Si le programme semble bloqué, appuyez sur Ctrl+C : Python interrompt l'exécution avec `KeyboardInterrupt`.

### Boucle infinie et équivalent de do while

Il arrive qu'une boucle infinie soit voulue : `while True:` avec une sortie par `break`. On utilise ce procédé pour écrire une boucle avec test final : Python n'a pas de construction `do while`, et ce schéma la remplace. Le bloc s'exécute au moins une fois, et la vérification se trouve à la fin.

```
while True:
    saisie = input("Montant : ")
    if saisie.isdigit():
        montant = int(saisie)
        break
    print("Saisissez un nombre entier")
```

Une boucle for infinie est rare : elle ne sert qu'à parcourir un itérateur sans fin, par exemple `itertools.count()`.

## break et continue : sortir de la boucle ou sauter une itération

`break` interrompt immédiatement la boucle, et l'exécution reprend après elle. `continue` ignore la fin de l'itération en cours et passe à la suivante.

```
depenses = [350, -10, 1200, 0, 99_999, 89]

for montant in depenses:
    if montant  50_000:
        print("Montant suspect, arrêt")
        break             # sortir de la boucle
    print(montant)
```

Le programme affiche 350 et 1200, puis le message : la boucle n'atteint jamais 89. Ces deux instructions n'agissent que sur la boucle la plus proche dans laquelle elles se trouvent.

### else dans une boucle

Les boucles `for` et `while` ont une branche `else` peu connue : elle s'exécute si la boucle s'est terminée normalement, sans `break`. C'est pratique pour une recherche :

```
for montant in depenses:
    if montant > 50_000:
        print("Une grosse dépense a été trouvée")
        break
else:
    print("Aucune grosse dépense")
```

## Boucles imbriquées

Une boucle à l'intérieur d'une autre exécute entièrement la boucle interne à chaque itération de la boucle externe. C'est ainsi qu'on parcourt des tableaux, des matrices ou qu'on forme des paires.

```
for ligne in range(1, 4):
    for colonne in range(1, 4):
        print(ligne * colonne, end="\t")
    print()
```

Deux remarques. D'abord, la complexité croît vite : deux boucles imbriquées sur 10 000 éléments représentent 100 millions d'opérations. Ensuite, `break` ne sort que de la boucle interne. Pour interrompre les deux, placez les boucles dans une fonction et utilisez `return` : c'est plus propre que des drapeaux.

## L'instruction match/case

Depuis Python 3.10, une longue chaîne `if commande == ... elif ...` peut être remplacée par l'instruction `match` (PEP 634). Ce n'est pas un simple switch : elle compare la valeur à un motif selon la forme des données et répartit directement les parties dans des variables.

```
def analyser(texte):
    match texte.split():
        case ["ajouter", article, montant]:
            return f"Ajouter {article} : {montant}"
        case ["liste"] | ["ls"]:
            return "Afficher les dépenses"
        case ["quitter"]:
            return "Sortie"
        case _:
            return "Commande inconnue"

print(analyser("ajouter Café 250"))  # Ajouter Café : 250
print(analyser("ajouter Café"))      # Commande inconnue
```

Le motif-liste `["ajouter", article, montant]` ne correspond qu'à une liste de trois éléments dont le premier vaut `"ajouter"`. Une commande sans montant tombe donc dans la branche `_`, qui attrape tous les autres cas. Le symbole `|` réunit plusieurs variantes.

### Dictionnaires, types et garde

Un motif-dictionnaire vérifie seulement les clés énumérées, les autres sont ignorées. L'écriture `int(a)` vérifie le type et capture la valeur, et un `if` placé après le motif ajoute une condition supplémentaire (on parle de garde) :

```
match evenement:
    case {"type": "depense", "montant": int(a)} if a > 10_000:
        print("Grosse dépense", a)
    case {"type": "depense", "montant": int(a)}:
        print("Dépense", a)
```

### Le piège principal de match

Un nom nu dans un `case` est une capture, et non une comparaison avec une variable. `case limite:` correspond à n'importe quelle valeur et l'écrit dans `limite`. Pour comparer à des constantes, utilisez un nom avec un point, par exemple `case Couleur.ROUGE:`, ou des littéraux.

La syntaxe de match n'a presque pas changé depuis 3.10. Python 3.15 corrige une petite dissymétrie : dans les motifs littéraux, seul le signe moins devant un nombre était autorisé ; on peut désormais écrire aussi `case +1:`. Sur les versions plus anciennes, ce code provoque une erreur de syntaxe.

## Erreurs typiques dans les boucles

- **Modifier une liste pendant son parcours.** Supprimer des éléments dans un `for` fait sauter leurs voisins. Il vaut mieux construire une nouvelle liste : `propres = [x for x in elements if x > 0]`.
- **Borne de range.** `range(1, n)` n'inclut pas `n`.
- **Oubli de modifier la condition d'un while** — boucle infinie.
- **Concaténer des chaînes avec += dans une boucle** : sur de gros volumes, c'est plus lent que `"".join(morceaux)`.
- **Affectation à la place de la comparaison** : `if x = 5` est une erreur de syntaxe ; la comparaison s'écrit `==`.

## Exercices sur les boucles

1. Calculez la somme et la moyenne d'une liste de dépenses en ignorant les valeurs négatives.
2. Affichez la table de multiplication de 1 à 9 à l'aide de boucles imbriquées.
3. Demandez à l'utilisateur des nombres jusqu'à ce qu'il saisisse une ligne vide, puis affichez le maximum.
4. Trouvez le premier nombre supérieur à 1000 dans une liste et signalez l'absence d'un tel nombre (avec `for ... else`).
5. Analysez les commandes `ajouter`, `supprimer`, `liste` avec `match`.

## En bref

Les boucles Python reposent sur deux constructions : `for` parcourt les éléments d'une collection ou d'un `range()`, `while` fonctionne tant que la condition est vraie. `break` et `continue` contrôlent le déroulement de la boucle, `enumerate()` et `zip()` évitent les compteurs manuels, et `if/elif/else` ainsi que `match/case` prennent les décisions. Tous ces outils sont mis en pratique, sur l'exemple d'un suivi de dépenses, dans la leçon du cours consacrée à Python.

## FAQ

**Quelle est la différence entre for et while en Python ?**

for parcourt une séquence déjà connue et sait seule quand s'arrêter, tandis que while se répète tant que la condition est vraie. Si le nombre de répétitions est connu ou qu'il y a une collection, prenez for ; si vous attendez un événement, prenez while.

**Comment parcourir une liste dans l'ordre inverse ?**

Utilisez reversed(elements) pour une collection, ou range(n - 1, -1, -1) pour des nombres. La fonction reversed ne copie pas la liste : elle la parcourt depuis la fin.

**Python possède-t-il un switch ?**

Il n'y a pas de switch séparé : son rôle est assumé par la chaîne if/elif et par l'instruction match/case, apparue en Python 3.10. match va plus loin : il analyse les listes et les dictionnaires selon leur forme et capture les valeurs.

**Qu'est-ce qui est plus rapide, une boucle ou une compréhension de liste ?**

Une compréhension de liste comme [x * 2 for x in elements] est en général un peu plus rapide qu'une boucle équivalente avec append, et plus courte. Pour une logique complexe à plusieurs conditions, la boucle classique se lit mieux.

**Comment sortir de deux boucles imbriquées d'un coup ?**

break ne sort que de la boucle interne. Le plus simple est de placer les boucles dans une fonction et d'en sortir avec return.


---
Source: Skillaria.Top (https://skillaria.top)
