Les boucles en Python
Répéter des actions avec les boucles while et for
La boucle while
La boucle while répète un bloc de code tant qu'une condition est vraie. La condition est évaluée avant chaque itération.
Syntaxe :
while condition:
# bloc répété tant que condition est vraie
compteur = 0
while compteur < 5:
print(f"Compteur : {compteur}")
compteur += 1
print("Boucle terminee !")
Sortie :
Compteur : 0
Compteur : 1
Compteur : 2
Compteur : 3
Compteur : 4
Boucle terminee !
Si la condition ne devient jamais fausse, la boucle tourne indéfiniment. Assurez-vous toujours qu'une variable dans la condition est modifiée à chaque itération. Utilisez Ctrl+C pour interrompre une boucle infinie.
# DANGER : boucle infinie !
x = 0
while x < 10:
print(x)
# Oubli : x n'est jamais incremente !
Utilisez while quand vous ne savez pas à l'avance combien d'itérations seront nécessaires (ex. : attendre une saisie valide de l'utilisateur). Utilisez for quand vous parcourez une séquence ou un nombre d'itérations connu.
La boucle for
La boucle for permet d'itérer sur n'importe quel iterable : liste, chaîne, range, dictionnaire, etc.
Syntaxe :
for variable in iterable:
# bloc exécuté pour chaque élément
fruits = ["pomme", "banane", "cerise"]
for fruit in fruits:
print(f"J'aime les {fruit}s")
Sortie :
J'aime les pommes
J'aime les bananes
J'aime les cerises
La fonction range()
range() génère une séquence d'entiers, très utile avec les boucles for.
| Appel | Séquence générée |
|---|---|
range(5) | 0, 1, 2, 3, 4 |
range(1, 6) | 1, 2, 3, 4, 5 |
range(0, 10, 2) | 0, 2, 4, 6, 8 |
range(10, 0, -1) | 10, 9, 8, 7, 6, 5, 4, 3, 2, 1 |
# Compter de 0 a 4
for i in range(5):
print(i)
# Compter de 1 a 10
for i in range(1, 11):
print(i)
# Nombres pairs de 0 a 8
for i in range(0, 10, 2):
print(i)
N'utilisez pas for i in range(len(ma_liste)): pour parcourir une liste. Préférez directement for element in ma_liste:. Si vous avez besoin de l'index ET de la valeur, utilisez enumerate() (voir plus bas).
Itérer sur des séquences
La boucle for fonctionne avec tous les types itérables.
Chaînes de caractères
mot = "Python"
for lettre in mot:
print(lettre)
# P, y, t, h, o, n (une lettre par ligne)
Listes avec condition
nombres = [3, -1, 7, -4, 9, -2, 5]
for n in nombres:
if n > 0:
print(f"{n} est positif")
Dictionnaires
personne = {"nom": "Alice", "age": 30, "ville": "Paris"}
# Parcourir les cles
for cle in personne:
print(cle)
# Parcourir les valeurs
for valeur in personne.values():
print(valeur)
# Parcourir les paires cle/valeur
for cle, valeur in personne.items():
print(f"{cle} : {valeur}")
Choisissez des noms de variables explicites : for fruit in fruits: est bien plus lisible que for x in fruits:. La variable de boucle doit décrire un élément de la collection.
break et continue
break : sortir de la boucle
break interrompt immédiatement la boucle et passe à la suite du programme.
nombres = [4, 7, 2, 9, 1, 6]
for n in nombres:
if n == 9:
print(f"Trouve : {n}")
break
print(f"Pas encore... ({n})")
continue : passer à l'itération suivante
continue saute le reste du bloc courant et passe à l'itération suivante.
for i in range(10):
if i % 2 == 0:
continue # saute les nombres pairs
print(i) # affiche uniquement 1, 3, 5, 7, 9
Plutôt que d'utiliser une variable "drapeau" (flag) pour signaler une sortie anticipée, préférez break : c'est plus explicite et plus Pythonique. Vous pouvez aussi utiliser le bloc else sur la boucle (voir ci-dessous) pour savoir si la boucle s'est terminée normalement.
Le else sur les boucles
Python offre une fonctionnalité rare : le bloc else sur une boucle. Il s'exécute uniquement si la boucle s'est terminée normalement (sans break).
nombres = [2, 4, 6, 8]
for n in nombres:
if n % 2 != 0:
print(f"Nombre impair trouve : {n}")
break
else:
print("Tous les nombres sont pairs !") # Affiche car pas de break
# Cas où le else ne s'exécute pas
nombres = [2, 5, 6, 8]
for n in nombres:
if n % 2 != 0:
print(f"Nombre impair trouve : {n}")
break
else:
print("Tous pairs") # N'est PAS affiché car break a été exécuté
Ce comportement est utile pour les recherches : si vous parcourez une liste sans trouver ce que vous cherchez, le else vous le confirme.
enumerate() : index et valeur simultanément
enumerate() retourne des paires (index, valeur) lors de l'itération.
fruits = ["pomme", "banane", "cerise"]
for index, fruit in enumerate(fruits):
print(f"{index}. {fruit}")
Sortie :
0. pomme
1. banane
2. cerise
On peut spécifier l'index de départ :
for index, fruit in enumerate(fruits, start=1):
print(f"{index}. {fruit}")
# 1. pomme, 2. banane, 3. cerise
Utilisez toujours enumerate() quand vous avez besoin de l'index ET de la valeur. for i, val in enumerate(liste): est bien plus lisible et Pythonique que for i in range(len(liste)): val = liste[i].
zip() : itérer sur deux listes en parallèle
zip() combine plusieurs itérables en paires (ou tuples).
noms = ["Alice", "Bob", "Charlie"]
notes = [18, 14, 16]
for nom, note in zip(noms, notes):
print(f"{nom} : {note}/20")
Sortie :
Alice : 18/20
Bob : 14/20
Charlie : 16/20
# zip avec trois listes
villes = ["Paris", "Lyon", "Marseille"]
populations = [2_161_000, 516_000, 861_000]
regions = ["Ile-de-France", "Auvergne-Rhone-Alpes", "Provence-Alpes-Cote d'Azur"]
for ville, pop, region in zip(villes, populations, regions):
print(f"{ville} ({region}) : {pop:,} habitants")
Les boucles imbriquées
On peut imbriquer des boucles pour traiter des structures à plusieurs dimensions.
# Table de multiplication
for i in range(1, 6):
for j in range(1, 6):
print(f"{i*j:4}", end="")
print() # Retour a la ligne apres chaque ligne
Sortie :
1 2 3 4 5
2 4 6 8 10
3 6 9 12 15
4 8 12 16 20
5 10 15 20 25
Évitez d'imbriquer plus de 2 niveaux de boucles. Une boucle triply imbriquée est souvent le signe qu'il faut refactoriser en fonctions. La complexité augmente exponentiellement avec les niveaux d'imbrication.
Les compréhensions de liste
Les compréhensions de liste sont une syntaxe concise et Pythonique pour créer des listes à partir d'une boucle.
Syntaxe : [expression for variable in iterable]
Avec filtre : [expression for variable in iterable if condition]
# Sans comprehension
carres = []
for x in range(1, 6):
carres.append(x**2)
print(carres) # [1, 4, 9, 16, 25]
# Avec comprehension (equivalent)
carres = [x**2 for x in range(1, 6)]
print(carres) # [1, 4, 9, 16, 25]
# Avec condition : garder seulement les positifs
nombres = [-3, 1, -5, 7, -2, 4]
positifs = [n for n in nombres if n > 0]
print(positifs) # [1, 7, 4]
# Transformer des chaines
mots = ["bonjour", "monde", "python"]
majuscules = [mot.upper() for mot in mots]
print(majuscules) # ['BONJOUR', 'MONDE', 'PYTHON']
# Filtrer et transformer
longues_majuscules = [mot.upper() for mot in mots if len(mot) > 5]
print(longues_majuscules) # ['BONJOUR', 'PYTHON']
Les compréhensions sont élégantes mais ne les surchargez pas. Si votre compréhension dépasse une ligne ou contient plusieurs conditions, utilisez une boucle for classique. La lisibilité prime toujours sur la concision.
Patrons pratiques courants
Accumulateur (somme)
notes = [14, 17, 12, 18, 15]
total = 0
for note in notes:
total += note
moyenne = total / len(notes)
print(f"Moyenne : {moyenne:.1f}") # Moyenne : 15.2
Compteur
texte = "Python est un langage de programmation"
compteur_voyelles = 0
for lettre in texte.lower():
if lettre in "aeiouy":
compteur_voyelles += 1
print(f"Nombre de voyelles : {compteur_voyelles}")
Recherche avec drapeau
# Verifier si une liste contient un nombre premier (approche naive)
nombres = [4, 6, 9, 7, 10]
premier_trouve = False
for n in nombres:
if n > 1:
est_premier = True
for i in range(2, n):
if n % i == 0:
est_premier = False
break
if est_premier:
print(f"Premier nombre premier : {n}")
premier_trouve = True
break
if not premier_trouve:
print("Aucun nombre premier dans la liste")