Listes et boucles for#
Qu'est-ce qu'une liste ?#
Là où une variable de type int, float, str, ou bool ne peut contenir qu'une seule valeur, une liste (type list) peut en contenir plusieurs. Les listes sont très pratiques quand un programme contient une grande quantité de données, afin de toutes les enregistrer dans une seule variable.
Une liste est entourée de crochets [] et ses valeurs sont séparées par des virgules ,.
panier = ["Poires", "Champignons", "Raviolis", "Pêches"]
print("Dans le panier il y a :", panier)
notes_math = [3.5, 4.8, 5.7, 4.1, 4.5, 5, 3.8, 5.9, 3.2, 4.4, 6]
print("Mes notes en math sont :", notes_math)
Astuce
Pour écrire des crochets sur :
Windows :
[AltGr+ è ou]AltGr+ !Mac :
[Option+ 5 ou]Option+ 6
Indexation#
L'indexation permet d'accéder à un élément précis d'une liste. Pour ce faire, on fait suivre la liste d'une paire de crochets [] entre lesquels on écrit l'index de l'élément souhaité. L'index correspond à la position de l'élément dans la liste, sachant que le premier élément a l'index 0, le deuxième l'index 1, etc.
1joueurs = ["Sommer", "Akanji", "Xhaka", "Embolo", "Freuler", "Vargas"]
2
3print("Liste complète :", joueurs)
4print("Premier joueur :", joueurs[0])
5print("5ème joueur :", joueurs[4])
Un index peut aussi être contenu dans une variable, ce qui permet par exemple de laisser l'utilisateur choisir l'élément à afficher.
1joueurs = ["Sommer", "Akanji", "Xhaka", "Embolo", "Freuler", "Vargas"]
2
3index = int(input("Quel index sélectionnes-tu ?"))
4print("Tu as sélectionné :", joueurs[index])
Important
Le premier élément d'une liste est toujours à l'index 0.
Dans une liste de n éléments, le dernier élément sera à l'index n-1.
Fonctions sur les listes#
En Python, il existe de nombreuses fonctions très pratiques pouvant être utilisées sur les listes. Voici celles que nous utiliserons dans ce cours.
len(ma_liste): retourne le nombre (=la longueur) d'éléments dansma_listelettres = ["S", "A", "L", "U", "T"] print(len(lettres))
ma_liste.append(element): ajoute un élément à la fin dema_listeoutils = ["tournevis", "vis", "vis", "vis", "clous", "marteau"] outils.append("scie") outils.append("hache") print(outils)ma_liste.remove(element): retire 1x l'élément dema_listeoutils = ["tournevis", "vis", "vis", "vis", "clous", "marteau"] outils.remove("clous") outils.remove("vis") print(outils)
Contrôler si un élément est dans une liste#
Sans lire manuellement chaque élément d'une liste, il est possible de tester si un élément en fait partie grâce à la structure if element in liste. Par exemple, le programme ci-dessous contrôle si un prénom fait partie des invités d'une fête.
1invités = ["Mila", "Loris", "Anja", "Kilian", "Sara", "Pedro"]
2prénom = input("Quel est ton prénom ?")
3
4if prénom in invités:
5 print("Bienvenue à la fête,", prénom)
6else:
7 print("Désolé, tu n'es pas sur la liste")
La liste peut même être écrite directement dans la condition :
1achat = input("Qu'as-tu acheté ?")
2
3if achat in ["pomme", "poire", "pêche", "abricot", "raisin"]:
4 print("C'est un fruit")
5elif achat in ["poivron", "chou-rouge", "carotte"]:
6 print("C'est un légume")
7else:
8 print("Je ne sais pas ce que c'est")
Parcourir chaque élément d'une liste#
Quand on traite les éléments d'une liste, il est courant de vouloir exécuter la même opération pour chacun de ses éléments. En Python, l'instruction Pour chaque ... dans ... se traduit avec les mots-clefs for ... in .... Les instructions indentées en dessous sont exécutées en boucle pour chaque élément de la liste : la nouvelle variable définie après le for prend tour à tour la valeur de chaque élément de la liste placée après le in.
1invités = ["Mila", "Loris", "Anja", "Kilian", "Sara", "Pedro"]
2
3#Pour chaque prénom dans la liste des invités
4for prénom in invités:
5 print("Bonjour", prénom)
La boucle for est souvent combinée à une variable qui accumule un résultat au fil des tours. Dans l'exemple ci-dessous, le programme compte le nombre de notes insuffisantes d'une liste.
1notes = [4.5, 5.75, 3.5, 4.25, 3, 5, 3.75, 4.5]
2nb_insuffisantes = 0
3
4#Pour chaque note dans la liste des notes
5for note in notes:
6 if note < 4:
7 print(note, ": Tu peux faire mieux !")
8 nb_insuffisantes = nb_insuffisantes + 1
9 else:
10 print(note, ": Bravo !")
11
12print("Au total il y a", nb_insuffisantes, "notes insuffisantes")
Important
for element in listeparcourt tous les éléments de la liste, du premier au dernier.Une variable qui accumule un résultat (un total, un compteur, un maximum) se définit avant la boucle, puis se met à jour dans la boucle.
La boucle for avec range()#
La fonction range() produit une suite de nombres entiers. Combinée à une boucle for, elle permet de répéter un bloc d'instructions un nombre précis de fois, sans devoir gérer soi-même un compteur comme avec un while. Les deux programmes ci-dessous affichent par exemple exactement la même chose.
Avec while | Avec for ... in range() |
|---|---|
compteur = 0
while compteur < 5:
print(compteur)
compteur = compteur + 1
|
for compteur in range(5):
print(compteur)
|
La fonction range() peut recevoir un, deux ou trois paramètres. Dans tous les cas, la valeur de fin n'est jamais atteinte : elle est exclue de la suite.
Instruction |
Nombres produits |
Explication |
|---|---|---|
|
|
de 0 jusqu'à 5 (exclu) |
|
|
de 2 jusqu'à 6 (exclu) |
|
|
de 0 jusqu'à 10 (exclu), de 3 en 3 |
|
|
de 10 jusqu'à 0 (exclu), en descendant de 2 en 2 |
1print("Compte à rebours :")
2for i in range(10, 0, -1):
3 print(i)
4print("Décollage !")
Parcourir les index d'une liste#
En combinant range() et len(), on obtient la suite de tous les index d'une liste : range(len(ma_liste)). Cela est utile lorsqu'on a besoin de connaître la position de chaque élément, et pas seulement sa valeur. Dans l'exemple ci-dessous, la variable i prend tour à tour les valeurs 0, 1, 2, etc., et arrivée[i] donne le coureur à cette position.
1arrivée = ["Isaac", "Victor", "Pascal", "Lucien", "Bruno", "Aurélien"]
2
3for i in range(len(arrivée)):
4 print(i + 1, ":", arrivée[i])
Connaître l'index permet aussi d'accéder aux voisins d'un élément. Le programme ci-dessous compare chaque température à celle du jour suivant pour compter le nombre de jours où il a fait plus chaud que la veille. Comme le dernier élément n'a pas de suivant, la boucle s'arrête à l'avant-dernier index, d'où le len(températures) - 1.
1températures = [12, 15, 14, 17, 19, 16, 18]
2nb_hausses = 0
3
4for i in range(len(températures) - 1):
5 if températures[i + 1] > températures[i]:
6 nb_hausses = nb_hausses + 1
7
8print("La température a augmenté", nb_hausses, "fois")
Important
range(fin),range(début, fin)etrange(début, fin, pas): la valeur de fin est toujours exclue.for element in listedonne directement les valeurs de la liste.for i in range(len(liste))donne les index de la liste : la valeur s'obtient alors avecliste[i].
Exercices#
Exercice 14#
Les trois instructions ci-dessous sont exécutées l'une après l'autre. Suivez le contenu de la liste à la main, puis répondez.
sac = ["pomme", "pain", "eau"]
sac.append("pomme")
sac.remove("pomme")
À la fin, que vaut
len(sac)?À la fin, que vaut
sac[0]?À la fin, que vaut
sac[2]?
Solution
Après le append, la liste vaut ["pomme", "pain", "eau", "pomme"].
Le remove ne retire qu'une seule occurrence, et c'est la première rencontrée : c'est
donc la pomme du début qui disparaît, pas celle de la fin. La liste finale vaut
["pain", "eau", "pomme"].
La liste a donc bien retrouvé sa longueur de départ, mais son contenu a changé d'ordre : le
premier élément n'est plus pomme mais pain.
Exercice 15#
Pour chacun des programmes ci-dessous, indiquez ce que vaut la variable indiquée à la fin de l'exécution. Répondez sans exécuter les programmes : parcourez la liste à la main, élément par élément.
Que vaut
total?nombres = [3, 7, 2, 9] total = 0 for n in nombres: total = total + n
Que vaut
compteur?mots = ["chat", "chien", "rat", "souris"] compteur = 0 for m in mots: if len(m) > 3: compteur = compteur + 1
Que vaut
resultat?notes = [3, 5, 4, 6] resultat = 0 for note in notes: resultat = note
Que vaut
produit?valeurs = [2, 3, 4] produit = 1 for v in valeurs: produit = produit * v
Que vaut
mot?lettres = ["P", "Y", "T", "H", "O", "N"] mot = "" for l in lettres: mot = mot + l
Solution
21. À chaque tour, l'élément est ajouté au total : 0, puis 3, 10, 12 et enfin 21. C'est le schéma de l'accumulateur, que l'on retrouve dans presque tous les exercices de cette page.
3. Seul
ratfait 3 lettres ;chat,chienetsourisen font plus de 3.6. Piège classique : l'instruction est
resultat = noteet nonresultat = resultat + note. La variable est donc écrasée à chaque tour et ne conserve que la dernière valeur de la liste. Une seule lettre de différence, et le programme ne fait plus du tout la même chose.24. Même schéma que le n° 1, mais avec une multiplication. Notez que
produitdoit partir de 1 et non de 0 : en partant de 0, tout produit vaudrait 0.PYTHON. L'accumulateur fonctionne aussi avec du texte :
+colle les chaînes les unes après les autres. La variable doit alors partir de la chaîne vide"".
Exercice 16#
Pour chacun des programmes ci-dessous, indiquez ce que vaut la variable indiquée à la fin de
l'exécution. Répondez sans exécuter les programmes : écrivez d'abord la suite de nombres produite
par le range(), puis suivez la boucle tour après tour.
Que vaut
total?total = 0 for i in range(5): total = total + i
Que vaut
total?total = 0 for i in range(1, 6): total = total + i
Que vaut
total?total = 0 for i in range(0, 10, 3): total = total + i
Que vaut
compteur?compteur = 0 for i in range(10, 0, -2): compteur = compteur + 1
Que vaut
compteur?valeurs = [3, 7, 5, 8, 2, 9] compteur = 0 for i in range(len(valeurs) - 1): if valeurs[i] > valeurs[i + 1]: compteur = compteur + 1
Solution
10.
range(5)produit0, 1, 2, 3, 4: le 5 est exclu. On a donc \(0 + 1 + 2 + 3 + 4 = 10\).15.
range(1, 6)produit1, 2, 3, 4, 5. Pour additionner les nombres de 1 à 5, la fin doit être fixée à 6.18.
range(0, 10, 3)produit0, 3, 6, 9: le nombre suivant, 12, dépasse la fin.5.
range(10, 0, -2)produit10, 8, 6, 4, 2: cinq nombres, le 0 étant exclu. La valeur dein'est pas utilisée ici, la boucle sert seulement à compter ses tours.2. La boucle compare chaque élément à son voisin de droite : 3 et 7, 7 et 5, 5 et 8, 8 et 2, puis 2 et 9. Seules les paires 7/5 et 8/2 sont dans le "mauvais" ordre. Notez le
len(valeurs) - 1: sans lui, au dernier tour,valeurs[i + 1]désignerait un élément qui n'existe pas.
Exercice 17#
Chacun des programmes suivants comporte au moins une erreur. Parfois, cette erreur fait directement buguer le programme avec un message d'erreur rouge. D'autres fois, le programme s'exécute correctement, mais son résultat n'est pas logique.
Corrigez chacun de ces codes de manière à ce qu'ils s'exécutent correctement et affichent un résultat logique.
1sac = [] #Définit une liste vide 2objet = input("Quel objet veux-tu mettre dans ton sac ?") 3while objet != "STOP": 4 append(sac.objet) 5 objet = input("Quel autre objet veux-tu mettre dans ton sac ?") 6print("Contenu du sac", sac)
1#Retire tous les 0 de la liste 2bits = [1, 0, 1, 1, 0, 1, 0] #Ne pas toucher à cette ligne 3bits.remove(0) 4print(bits)
1#Affiche la liste des tâches à faire avec le texte TODO avant chaque tâche 2todo = ["Réviser math", "Devoir de français", "Apprendre Scedryk par coeur"] 3for tâche in todo: 4 print("TODO :", todo)
1votes = ["oui", "non", "non", "oui", "oui", "non", "non", "oui", "non", "oui", "oui"] 2oui = 0 3non = 0 4for v in votes: 5 if v == "oui": 6 oui += 1 7 elif v == "non": 8 non += 1 9 10 if oui > non: 11 print("Les OUI l'emportent") 12 elif non > oui: 13 print("Les NON l'emportent") 14 else: 15 print("Egalité")
1#Affiche les nombres de 1 à 10 2for i in range(10): 3 print(i)
1#Compte combien de fois un nombre est suivi d'un nombre plus grand 2nombres = [4, 9, 2, 7, 7, 10] 3compteur = 0 4for i in range(len(nombres)): 5 if nombres[i + 1] > nombres[i]: 6 compteur += 1 7print(compteur)
Solution
1sac = [] #Définit une liste vide 2objet = input("Quel objet veux-tu mettre dans ton sac ?") 3while objet != "STOP": 4 sac.append(objet) 5 objet = input("Quel autre objet veux-tu mettre dans ton sac ?") 6print("Contenu du sac", sac)
1#Retire tous les 0 de la liste 2bits = [1, 0, 1, 1, 0, 1, 0] #Ne pas toucher à cette ligne 3while 0 in bits: 4 bits.remove(0) 5print(bits)
remove()ne retire qu'une seule occurrence de la valeur, et la liste en contient trois. Plutôt que d'écrire trois foisbits.remove(0), on répète leremovetant que la liste contient encore un0: ce programme fonctionne quel que soit le nombre de zéros.1#Affiche la liste des tâches à faire avec le texte TODO avant chaque tâche 2todo = ["Réviser math", "Devoir de français", "Apprendre Scedryk par coeur"] 3for tâche in todo: 4 print("TODO :", tâche)
À chaque tour, c'est la variable
tâchequi contient l'élément courant. Affichertodoaffiche la liste complète à chaque tour.1votes = ["oui", "non", "non", "oui", "oui", "non", "non", "oui", "non", "oui", "oui"] 2oui = 0 3non = 0 4for v in votes: 5 if v == "oui": 6 oui += 1 7 elif v == "non": 8 non += 1 9 10if oui > non: 11 print("Les OUI l'emportent") 12elif non > oui: 13 print("Les NON l'emportent") 14else: 15 print("Egalité")
Le résultat du vote ne doit être affiché qu'une seule fois, une fois que tous les votes ont été comptés : le
iffinal doit donc être sorti de la boucle (désindenté).1#Affiche les nombres de 1 à 10 2for i in range(1, 11): 3 print(i)
La valeur de fin d'un
range()est toujours exclue, etrange(10)commence à 0 : il produit donc les nombres de 0 à 9.1#Compte combien de fois un nombre est suivi d'un nombre plus grand 2nombres = [4, 9, 2, 7, 7, 10] 3compteur = 0 4for i in range(len(nombres) - 1): 5 if nombres[i + 1] > nombres[i]: 6 compteur += 1 7print(compteur)
Au dernier tour,
ivaut l'index du dernier élément, etnombres[i + 1]n'existe pas (list index out of range). Comme le dernier élément n'a pas de suivant, la boucle doit s'arrêter à l'avant-dernier index.
Exercice 18#
Complétez le programme ci-dessous afin que l'utilisateur puisse petit à petit
créer une liste avec les codes postaux dans lesquels il souhaite se rendre.
Cette liste des codes postaux ne doit jamais contenir de doublons ! Si
l'utilisateur essaie d'en entrer un, le programme affichera Erreur, ce code postal est déjà dans la liste et continuera ensuite normalement. Le programme
s'arrête quand l'utilisateur entre un code postal négatif. À ce moment, la liste
des codes postaux est simplement affichée.
1# Complétez le programme
2codes_postaux = []
3code_postal = int(input("Entre un code postal: "))
4
5while code_postal >= 0:
6 # Complétez le programme à partir de là
Solution
1codes_postaux = []
2code_postal = int(input("Entre un code postal : "))
3while code_postal >= 0:
4 if code_postal in codes_postaux:
5 print("Erreur, ce code postal est déjà dans la liste.")
6 else:
7 codes_postaux.append(code_postal)
8 code_postal = int(input("Entre un code postal : "))
9
10print(codes_postaux)
Exercice 19#
La liste ci-dessous contient toutes les notes d'un bulletin. Avec cette liste, calculez les valeurs suivantes :
Le nombre de bonnes notes (4.5 et plus).
La moyenne. On calcule une moyenne en additionnant toutes les valeurs, puis en les divisant par leur nombre.
La meilleure note obtenue.
1notes = [3.6, 5.7, 3.6, 5.8, 2.2, 5.2, 2.4, 4.6, 2.8, 3.6, 3.8, 4.1]
2
3# Complétez le programme à partir de là
4nb_bonnes_notes =
5moyenne =
6meilleure_note =
7
8print("Il y a", nb_bonnes_notes, "bonnes notes.")
9print("La moyenne est de", moyenne)
10print("La meilleure note obtenue est", meilleure_note)
Solution
1notes = [3.6, 5.7, 3.6, 5.8, 2.2, 5.2, 2.4, 4.6, 2.8, 3.6, 3.8, 4.1]
2
3#Calcul du nombre de bonnes notes
4nb_bonnes_notes = 0
5for note in notes:
6 if note >= 4.5:
7 nb_bonnes_notes += 1
8
9#Calcul de la moyenne
10moyenne = 0
11for note in notes:
12 moyenne += note
13moyenne = moyenne / len(notes)
14
15#Calcul de la meilleure note
16meilleure_note = 0
17for note in notes:
18 if note > meilleure_note:
19 meilleure_note = note
20
21print("Il y a", nb_bonnes_notes, "bonnes notes.")
22print("La moyenne est de", moyenne)
23print("La meilleure note obtenue est", meilleure_note)
Exercice 20#
Écrivez un programme qui vérifie si une liste de nombres est triée dans l'ordre croissant,
c'est-à-dire si chaque élément est plus petit ou égal à celui qui le suit. Le programme affichera
La liste est triée ou La liste n'est pas triée. Testez-le avec les trois listes proposées.
1nombres = [2, 5, 5, 8, 13, 21] # triée
2#nombres = [2, 5, 4, 8, 13, 21] # pas triée
3#nombres = [21, 13, 8, 5, 2] # pas triée
4
5#Écrivez votre code ici
Solution
1nombres = [2, 5, 5, 8, 13, 21]
2
3triée = True
4for i in range(len(nombres) - 1):
5 if nombres[i] > nombres[i + 1]:
6 triée = False
7
8if triée:
9 print("La liste est triée")
10else:
11 print("La liste n'est pas triée")
On part du principe que la liste est triée, et on cherche une preuve du contraire : il suffit d'une seule paire de voisins dans le mauvais ordre pour que la liste ne soit pas triée.
Il ne faut surtout pas remettre
triée = Truedans unelseà l'intérieur de la boucle : la dernière paire comparée effacerait alors le résultat de toutes les précédentes.La boucle s'arrête à l'avant-dernier index, car le dernier élément n'a pas de voisin de droite.
Exercice 21#
Écrivez un programme qui crée une nouvelle liste inverse contenant les éléments de la liste
podium dans l'ordre inverse, puis l'affiche. Utilisez une boucle for avec un range() qui
parcourt les index en partant de la fin. Le programme doit afficher :
['Bronze', 'Argent', 'Or']
1podium = ["Or", "Argent", "Bronze"]
2inverse = []
3
4#Complétez le programme ici
Solution
1podium = ["Or", "Argent", "Bronze"]
2inverse = []
3
4for i in range(len(podium) - 1, -1, -1):
5 inverse.append(podium[i])
6
7print(inverse)
Le dernier index de la liste est
len(podium) - 1, c'est donc le début durange().On veut descendre jusqu'à l'index
0compris. Comme la fin est toujours exclue, il faut indiquer-1comme valeur de fin.Le pas de
-1fait descendre les index un par un :range(2, -1, -1)produit2, 1, 0.