Les boucles permettent d'exécuter du code et de répéter des instructions sans les réécrire à chaque fois. Elles sont très pratiques pour les tâches répétitives, et permettent de parcourir des données et de créer des algorithmes.
Il existe deux types de boucle : for et while :
-
La boucle
forest utilisée pour parcourir des itérables (listes, dictionnaires, tuples, chaînes de caractères, range...). -
La boucle
whileva exécuter un bloc de code tant que la condition qui lui est donnée est vraie.
La boucle for
Une boucle for s'écrit de la manière suivante :
for element in mon_iterable: ... # code
La variable element prend la valeur de chaque élément contenu dans mon_iterable à chaque itération.
La boucle for continue jusqu'à ce qu'on ait atteint le dernier élément de mon_iterable.
Prenons un exemple :
for element in [1, 2, 3, 4]: print(element) # Résultat : # 1 # 2 # 3 # 4
Que se passe-t-il en arrière plan ?
En réalité, lorsqu'on utilise une boucle for sur un objet itérable, Python va appeler la fonction iter en arrière plan. De ce fait, l'itérable est transformé en itérateur, c'est-à-dire un objet possédant la méthode __next__ permettant de récupérer les éléments l'un après l'autre. Cette méthode est appelée jusqu'à ce que l'exception StopIteration soit levée.
Dans cet exemple, nous utilisons les fonctions iter et next :
ma_liste = [10, 20, 30] # Appel de iter de manière explicite iterateur = iter(ma_liste) # Utilisation de next() pour récupérer les éléments un par un print(next(iterateur)) # Affiche : 10 print(next(iterateur)) # Affiche : 20 print(next(iterateur)) # Affiche : 30 # Appel supplémentaire à next() qui lève l'exception StopIteration print(next(iterateur))
On pourrait même reproduire le mécanisme de la boucle for :
ma_liste = [10, 20, 30] iterateur = iter(ma_liste) while True: try: element = next(iterateur) print(element) except StopIteration: # La boucle while s'arrête dès que StopIteration est levée break print("Fin du script")
for ... else
Commençons par un exemple :
for el in [1, 10, 20, 50]: print(el) else: print("La boucle s'est terminée sans break") """ Résultat : 1 10 20 50 La boucle s'est terminée sans break """
Ici, le code dans l'instruction else est exécuté lorsque la boucle passe sur l'itérable en entier.
Le code dans l'instruction else ne sera donc pas exécuté si l'instruction break est appelée :
for el in [1, 10, 20, 50]: print(el) if el > 10: break else: print("La boucle s'est terminée sans break") """ Résultat : 1 10 20 """
On remarque que l'instruction else associée à la boucle for est exécutée seulement si la boucle se termine normalement, c'est-à-dire sans être interrompue par l'instruction break.
Maintenant, regardons ce qui se passe avec un exemple plus classique :
noms = ["Alice", "Bob", "Charlie", "David"] recherche = "Patrick" for nom in noms: if nom == recherche: print(f"{recherche} est présent(e) dans la liste.") break else: # Le bloc else n'est exécuté que si la boucle se termine # sans rencontrer de break, c'est-à-dire quand "Patrick" n'a pas été trouvé print(f"{recherche} est introuvable dans la liste.")
Nous cherchons un élément spécifique dans la liste. Dans ce cas, le bloc else sera exécuté seulement si Patrick est introuvable.
Utiliser la boucle for avec différents types d'itérables
Précédemment, nous avons utilisé la boucle for avec une liste.
Mais comme nous l'avons vu, il est possible d'utiliser la boucle for avec différents itérables comme les tuples :
mon_tuple = (1, 2, 3) for valeur in mon_tuple: print(valeur) """ Résultat : 1 2 3 """
Les chaînes de caractères :
ma_chaine = "Patrick" for caractere in ma_chaine: print(caractere) """ Résultat : P a t r i c k """
Les sets :
mon_set = {1, 2, 3, 4} for element in mon_set: print(element) """ Résultat : 1 2 3 4 """
Les dictionnaires :
mon_dict = {"a": 1, "b": 2, "c": 3} # Itération sur les clés for cle in mon_dict: print(cle) # Résultat: # a # b # c # Itération sur les valeurs for valeur in mon_dict.values(): print(valeur) # Résultat: # 1 # 2 # 3 # Itération sur les items (clé, valeur) for cle, valeur in mon_dict.items(): print(cle, valeur) # Résultat: # a 1 # b 2 # c 3
L'objet range :
# Exemple : itérer sur une séquence d'entiers de 0 à 4 for i in range(5): print(i) """ Résultat : 0 1 2 3 4 """
La boucle while
La boucle while est utilisée pour exécuter du code tant qu'une certaine condition est vérifiée.
Cette boucle est très utile lorsque le nombre d'itérations n'est pas connu à l'avance et peut varier selon une condition.
Elle s'écrit de la manière suivante :
while condition: ... # Bloc de code
Prenons un exemple concret :
compteur = 0 while compteur < 3: print("Compteur vaut :", compteur) compteur += 1 # Résultat : # Compteur vaut : 0 # Compteur vaut : 1 # Compteur vaut : 2
Dans ce cas, tant que le compteur est inférieur à 3, le code qui est dans la boucle va continuer à s'exécuter.
Prenons un autre exemple plus complexe :
# Définition d'une hiérarchie imbriquée avec trois niveaux d'enfants hierarchie = { "name": "racine", "child": { "name": "enfant1", "child": { "name": "enfant2", "child": { "name": "Patrick" # Ici, il n'y a pas de clé "child", indiquant la fin de la hiérarchie } } } } # On commence par le premier élément de la hiérarchie current = hierarchie # Tant que l'élément courant possède la clé "child", on affiche le nom et on descend d'un niveau while "child" in current: print(current["name"]) current = current["child"] # Affichage du dernier élément (celui qui n'a pas de clé "child") print(f"Le dernier c'est ... {current['name']} !")
La boucle while permet de parcourir une structure de données hiérarchique avec imbrication. Dans le dictionnaire, chaque élément peut contenir un enfant via la clé child. Bien que l'on ne connaisse pas forcément le nombre d'imbrication à l'avance, la condition d'arrêt va dynamiquement récupérer les enfants.
while ... else
Le fonctionnement de else associé à une boucle while est similaire à celui de la boucle for : si la boucle se termine sans être interrompue par l'instruction break, alors le bloc else sera exécuté.
i = 0 while i < 3: print(i) i += 1 else: print("Boucle terminée normalement") # Résultat : # 0 # 1 # 2 # Boucle terminée normalement
i = 0 while i < 5: if i == 2: break print(i) i += 1 else: print("Boucle terminée normalement") # Résultat : # 0 # 1
Exemple avec une saisie de l'utilisateur
La boucle while permet de contrôler une logique répétitive jusqu'à ce qu'une certaine condition soit remplie :
choix = "" while choix != "stop": print("Le choix 'stop' permet de sortir de la boucle.") choix = input("Quel est ton choix ? ")
Ici, si la saisie de l'utilisateur est stop, alors il sortira de la boucle.
Risque de boucle infinie
Attention
Il est important de s'assurer que la condition d'arrêt soit atteinte. Sinon, il y a un risque de boucle infinie.
# Risque de boucle infinie # i = 0 # while i < 10: # print(i) # # oublie de l'incrémentation : i += 1
Boucles imbriquées
Il est possible de placer une boucle à l'intérieur d'une autre. Ce qui peut être utile pour parcourir des collections plus complexes.
matrice = [ [1, 2], [3, 4], [5] ] for element in matrice: print(element) for sous_element in element: print(sous_element) # Résultat : # [1, 2] # 1 # 2 # [3, 4] # 3 # 4 # [5] # 5
Dans cet exemple, la boucle externe parcourt chaque ligne (en récupérant les sous-listes), tandis que la boucle interne parcourt chaque élément de la ligne (en récupérant chaque élément des sous-listes).
Attention
Attention, les boucles imbriquées peuvent multiplier le nombre total d'itérations de manière conséquente et influer sur les performances de votre script.
À noter qu'il est possible d'imbriquer des boucles while, ainsi que de combiner des boucles while et for.
# Pour chaque valeur i de 0 à 2, # la boucle while s'exécute tant que j est inférieur à 2. for i in range(3): j = 0 while j < 2: print(f"for/while -> i: {i}, j: {j}") j += 1 # Résultat : # for/while -> i: 0, j: 0 # for/while -> i: 0, j: 1 # for/while -> i: 1, j: 0 # for/while -> i: 1, j: 1 # for/while -> i: 2, j: 0 # for/while -> i: 2, j: 1
Dans cet exemple, pendant l' itération de la boucle for, while s'exécute deux fois.
# La boucle while s'exécute tant que i est inférieur à 3. # Pour chaque itération, la boucle for parcourt les nombres de 0 à 1. i = 0 while i < 3: for j in range(2): print(f"while/for -> i: {i}, j: {j}") i += 1 # Résultat : # while/for -> i: 0, j: 0 # while/for -> i: 0, j: 1 # while/for -> i: 1, j: 0 # while/for -> i: 1, j: 1 # while/for -> i: 2, j: 0 # while/for -> i: 2, j: 1
Pour celui-ci, à chaque itération de while, la boucle for va s'exécuter deux fois.
Les compréhensions de liste
Les compréhensions de liste permettent la création de listes en une unique ligne de code. Elles sont très pratiques pour transformer et filtrer des données, et peuvent remplacer l'usage de boucles for classiques.
carres = [x**2 for x in range(10)] print(carres) # Résultat : [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
Avec une boucle for traditionnelle :
carres = [] for i in range(10): carres.append(i**2) print(carres) # Résultat : [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
Pour plus d'informations sur les compréhensions de liste, n'hésitez pas à lire notre glossaire sur le sujet.
break et continue
Les instructions break et continue permettent de contrôler l'exécution des boucles.
break
L'instruction break permet de sortir prématurément d'une boucle. On l'utilise souvent avec une structure conditionnelle pour sortir d'une boucle dans certaines conditions :
for i in range(10): if i == 5: break # Arrête la boucle dès que i vaut 5 print(i) # Résultat : # 0 # 1 # 2 # 3 # 4
continue
L'instruction continue permet de passer à l'itération suivante de la boucle en ignorant le code de l'itération courante.
for i in range(10): if i == 5: continue # Ignore l'itération où i vaut 5 print(i) # Résultat : # 0 # 1 # 2 # 3 # 4 # 6 # 7 # 8 # 9