Aller au contenu

Les boucles Pour (avec for)

Attention

Cette partie sur les boucles for est fondamentale. N'hésitez pas à la refaire plus tard jusqu'à ce que vous ayiez bien compris.

Les boucles permettent une répétition d'instructions.

Le nombre de répétitions peut être connu au départ (boucle Pour) ou pas (boucle Tant que).

Dans le cas d'une boucle Pour, nous demandons à une variable de prendre toutes les valeurs successives d'une collection de valeurs.

Exemple 1

###(Dés-)Active le code après la ligne # Tests (insensible à la casse)
(Ctrl+I)
Entrer ou sortir du mode "deux colonnes"
(Alt+: ; Ctrl pour inverser les colonnes)
Entrer ou sortir du mode "plein écran"
(Esc)
Tronquer ou non le feedback dans les terminaux (sortie standard & stacktrace / relancer le code pour appliquer)
Si activé, le texte copié dans le terminal est joint sur une seule ligne avant d'être copié dans le presse-papier

Cet exemple se lit ainsi : la variable fruit doit prendre chacune des valeurs de la liste ["pomme", "poire", "cerise"] (dans l'ordre), afficher le texte "Je mange une" suivi de la valeur de fruit.

L'instruction print("Je mange une", fruit) est ici exécutée trois fois, nous dirons qu'il y a eu trois itérations.

Bien sûr, comme d'habitude, le nom de la variable fruit peut être changé (nous pouvons même mettre _ à la place !) mais autant choisir un nom facile à comprendre.

Ouvrez Python Tutor (avec Ctrl + clic gauche). Copiez-collez le code de l'exemple 1 puis cliquez sur "Visualize Execution" pour observer l'exécution de votre code pas à pas (regardez en particulier le mouvement de la flèche verte et les valeurs de la variable fruit).

Exemple 2

###(Dés-)Active le code après la ligne # Tests (insensible à la casse)
(Ctrl+I)
Entrer ou sortir du mode "deux colonnes"
(Alt+: ; Ctrl pour inverser les colonnes)
Entrer ou sortir du mode "plein écran"
(Esc)
Tronquer ou non le feedback dans les terminaux (sortie standard & stacktrace / relancer le code pour appliquer)
Si activé, le texte copié dans le terminal est joint sur une seule ligne avant d'être copié dans le presse-papier

Cet exemple montre qu'une chaîne de caractères est (un peu comme son nom l'indique...) une succession de caractères.

À retenir

La syntaxe générale est :

début du programme
for variable in collection_objets:
    bloc dinstructions à exécuter un certain nombre (la taille de la collection) de fois
suite du programme
graph LR
A[début]-->B{boucle}
B-->|boucle non terminée| C[instructions dans le for]
B-->|boucle terminée| D[suite du programme]
C-->|répétition|B

Remarquez les points communs avec def et if :

  • le : indispensable à la fin de la ligne du for ;
  • le bloc d’instructions à repéter est indenté.

Une collection d'objets est appelée un itérable.

Enfin, remarquez qu'il y a trois étapes, un peu cachées :

  • Initialisation : la variable est initialisée à la première valeur de la collection d'objets.
  • Condition : tant que toutes les valeurs de la collection d'objets n'ont pas toutes été lues.
  • Incrémentation : la valeur de variable prendra à chaque itération la valeur suivante dans la collection d'objets.

Accumulateurs

Exemple 3

Lisez le script ci-dessous puis, sur papier, trouvez ce qu'il va afficher. Exécutez-le ensuite pour vérifier.

texte = "J'aime "
for fruit in ["pommes", "poires", "cerises"]:
    texte = texte + "les " + fruit + ","
print(texte)
###(Dés-)Active le code après la ligne # Tests (insensible à la casse)
(Ctrl+I)
Entrer ou sortir du mode "deux colonnes"
(Alt+: ; Ctrl pour inverser les colonnes)
Entrer ou sortir du mode "plein écran"
(Esc)
Tronquer ou non le feedback dans les terminaux (sortie standard & stacktrace / relancer le code pour appliquer)
Si activé, le texte copié dans le terminal est joint sur une seule ligne avant d'être copié dans le presse-papier
Explication

Ici, la boucle a permis de construire progressivement la valeur de la variable texte, prenons le temps de voir comment :

Une variable dont la valeur est constituée grâce à une boucle est parfois appelée un accumulateur.

Attention

Quand vous en utilisez un, n'oubliez pas d'initialiser le ou les accumulateur(s) avant l'entrée dans la boucle (essayez d'enlever texte = "J'aime " pour voir).

Chaîne vide etc.

Il est très fréquent d'initialiser un accumulateur à une valeur vide, pour les chaînes de caractères c'est '' (ou ""), pour une somme de nombres c'est 0 et pour un produit ce serait 1.

Exercice 1

Complétez le script suivant pour qu'il multiplie les nombres présents dans la liste liste_nbs :

###(Dés-)Active le code après la ligne # Tests (insensible à la casse)
(Ctrl+I)
Entrer ou sortir du mode "deux colonnes"
(Alt+: ; Ctrl pour inverser les colonnes)
Entrer ou sortir du mode "plein écran"
(Esc)
Tronquer ou non le feedback dans les terminaux (sortie standard & stacktrace / relancer le code pour appliquer)
Si activé, le texte copié dans le terminal est joint sur une seule ligne avant d'être copié dans le presse-papier

Exercices

Exercice 2 : compléter un script qui retourne un texte.

Exercice 3 : compléter un script qui duplique les lettres d'un texte.

Exercice 4 : recopier un mot suivant sa taille.

Exercice 5 : souligner des mots.

Exercice 6 : pour les plus rapides.

Exercice 6b : variante du 6 en un peu plus dur.

Boucle et condition

Exemple 4

Essayez de comprendre puis exécutez ce script :

###(Dés-)Active le code après la ligne # Tests (insensible à la casse)
(Ctrl+I)
Entrer ou sortir du mode "deux colonnes"
(Alt+: ; Ctrl pour inverser les colonnes)
Entrer ou sortir du mode "plein écran"
(Esc)
Tronquer ou non le feedback dans les terminaux (sortie standard & stacktrace / relancer le code pour appliquer)
Si activé, le texte copié dans le terminal est joint sur une seule ligne avant d'être copié dans le presse-papier
Explication

Seules les lettres du texte "A vaincre sans péril, on triomphe sans gloire." qui ne sont pas des voyelles sont ajoutées au texte réduit. Ce script supprime donc les voyelles d'un texte.

Remarquez la double indentation de l'instruction texte_reduit = texte_reduit + lettre (qui est dans le if, lui-même dans le for).

Exercice 7

  1. Modifiez le script de l'exemple 4 pour qu'il compte les voyelles dans le texte.
  2. Ecrivez une fonction comptage_voyelles qui prend une chaine de caractères et renvoie le nombre de voyelles.
    Par exemple comptage_voyelles("A vaincre sans péril, on triomphe sans gloire.") donnera 15.

###(Dés-)Active le code après la ligne # Tests (insensible à la casse)
(Ctrl+I)
Entrer ou sortir du mode "deux colonnes"
(Alt+: ; Ctrl pour inverser les colonnes)
Entrer ou sortir du mode "plein écran"
(Esc)
Tronquer ou non le feedback dans les terminaux (sortie standard & stacktrace / relancer le code pour appliquer)
Si activé, le texte copié dans le terminal est joint sur une seule ligne avant d'être copié dans le presse-papier

Exercices

Exercice 8 : compter le nombre de "i" dans une chaîne.

Exercice 9 (variante) : fonction pour compter le nombre d'apparitions d'un caractère dans une chaîne.

Exercices

Si vous avez fini le reste :

Exercice 10 : remplacer des voyelles par autre chose.

Exercice 11 : supprimer une lettre sur deux dans une chaîne.

La fonction range

Bart a encore eu une punition, il doit recopier 100 fois le texte "Je ne me laisserai pas aller à la facilité". Comme il a du mal a écrire à la main (c'est fatiguant, vous comprenez), il décide d'utiliser un ordinateur :

print("Je ne me laisserai pas aller à la facilité")
print("Je ne me laisserai pas aller à la facilité")
print("Je ne me laisserai pas aller à la facilité")
print("Je ne me laisserai pas aller à la facilité")

mais même en utilisant le copier-coller, c'est laborieux...

Sa soeur, qui le prend en pitié, lui dit que les boucles sont utiles pour cela. Il tente alors :

for n in [1, 2, 3, 4, 5, ...]:
    print("Je ne me laisserai pas aller à la facilité")

mais il faut taper tous les entiers jusqu'à 100...

Heureusement, la fonction range de Python va l'aider.

Tapez ci-dessous l'instruction list(range(100)). Que remarquez-vous ?

Tronquer ou non le feedback dans les terminaux (sortie standard & stacktrace / relancer le code pour appliquer)
Si activé, le texte copié dans le terminal est joint sur une seule ligne avant d'être copié dans le presse-papier
Réponses
  • la fonction range génère une séquence d'entiers consécutifs ;
  • l'instruction range(100) génère une séquence de 100 nombres ;
  • le dernier nombre n'est pas 100 mais 99.

Exercice 12

Écrivez une commande qui fera gagner du temps (mais pas forcément de la bonne conscience) à Bart.

Tronquer ou non le feedback dans les terminaux (sortie standard & stacktrace / relancer le code pour appliquer)
Si activé, le texte copié dans le terminal est joint sur une seule ligne avant d'être copié dans le presse-papier

À retenir

  • Il y a trois syntaxes pour la fonction range :
    • range(n) donne une liste de n nombres entiers, de 0 à n-1 ;
    • range(deb, fin) donne une liste des entiers entre deb inclus jusqu'à fin exclus ;
    • range(deb, fin, pas) donne une liste des entiers entre deb inclus jusqu'à fin exclus, avec un écart de pas entre chaque.
  • Elle est très utilisée avec for pour répéter des instructions un certain nombre de fois.

Exercice 13

Générez avec la fonction range les listes suivantes :

  • 0, 1, 2, ..., 42
  • 42, 43, 44, ..., 75
  • 13, 16, 19, 22, 25, ..., 97

Tronquer ou non le feedback dans les terminaux (sortie standard & stacktrace / relancer le code pour appliquer)
Si activé, le texte copié dans le terminal est joint sur une seule ligne avant d'être copié dans le presse-papier

Exercices

Exercice 14 : lecture d'un script.

Exercice 15 : table de multiplication par 3.

Exercice 16 : table de multiplication.

Exercice 17 : somme d'entiers.

Exercice 18 : dessiner un carré avec une tortue !

Exercice 19 : dessiner un escalier avec une tortue !

Exercice

Si vous avez fini les cinq exercices ci-dessus :

Exercice 20 : fonction pour dessiner des carrés quelconques.

Modifiez votre fonction pour qu'elle permette de spécifier la couleur du carré également.

Essayez d'écrire une fonction carré_aléatoire qui dessine un carré de taille, couleur et position aléatoire. Dans une boucle, exécutez cette fonction 20 fois (par exemple).

Petit bêtisier des erreurs courantes sur les boucles for

  1. Le(s) paramètre(s) de la fonction range est (sont) toujours entier(s) donc pas de range(5.2), ni de range('abcde'), ni de range(a)a n'est pas un entier (erreur plus difficile à détecter... → nommez mieux vos variables).
  2. Quand vous utilisez un accumulateur, utilisez quelque chose comme ceci :
    s = 0
    for n in range(20):
        s = s + n
    
    et pas comme cela :
    s = 0
    for n in range(20):
        s = n
    
    Il est essentiel que vous fassiez la différence entre ces deux scripts !

Boucles imbriquées

Il est parfois utile de mettre une boucle dans une boucle.

Exemple 1

Affichons toutes les heures possibles :

###(Dés-)Active le code après la ligne # Tests (insensible à la casse)
(Ctrl+I)
Entrer ou sortir du mode "deux colonnes"
(Alt+: ; Ctrl pour inverser les colonnes)
Entrer ou sortir du mode "plein écran"
(Esc)
Tronquer ou non le feedback dans les terminaux (sortie standard & stacktrace / relancer le code pour appliquer)
Si activé, le texte copié dans le terminal est joint sur une seule ligne avant d'être copié dans le presse-papier

Parfois la variable utilisée pour la deuxième boucle dépend de celle utilisée pour la première.

Exemple 2

Comment afficher les coordonnées de tous les points du triangle suivant :

points dans un triangle

(on pourrait aussi envisager un traitement sur ces points, par exemple un changement de couleur, un déplacement, etc.)

Réponse
for x in range(5): # x va de 0 à 4
    for y in range(5 - x): # ainsi, quand x vaut 0, y va de 0 à 4, etc.
        print("Coordonnées : (", x, ",", y, ")")

Exercice 21

Tables de multiplication .

Exercices

Si vous avez fini, deux exercices (pas forcément sur les boucles imbriquées) :

  1. Exercice 22 : fréquence du six lors de lancers de dés.
  2. Exercice 23 : calcul d'intérêts composés.