07 - Listes
Exercice 1 : QCM – vérification des prérequis
Pour chaque question, une seule réponse est correcte.
1. Que vaut len([3, 1, 4, 1, 5]) ?
- A. 4
- B. 5
- C. 14
- D. Erreur
Correction
Réponse : B. len() renvoie le nombre d’éléments de la liste, soit cinq. Les doublons comptent.
- A est faux : erreur de comptage (oubli d’un élément).
- C est faux : confusion entre
len()(nombre d’éléments) etsum()(somme des éléments : $3+1+4+1+5 = 14$). - D est faux :
len()s’applique parfaitement à une liste.
2. On définit L = [10, 20, 30, 40]. Que vaut L[2] ?
- A. 10
- B. 20
- C. 30
- D. 40
Correction
Réponse : C. L’indexation commence à 0 : L[0] = 10, L[1] = 20, L[2] = 30.
- A est faux : c’est
L[0]. - B est faux : c’est
L[1]. Erreur classique consistant à commencer l’indexation à 1. - D est faux : c’est
L[3].
3. Quel est l’effet de L.append(50) sur la liste L = [10, 20, 30] ?
- A.
Lvaut[50, 10, 20, 30] - B.
Lvaut[10, 20, 30, 50] - C.
Lvaut[10, 20, 50, 30] - D. Cela renvoie une nouvelle liste
[10, 20, 30, 50]sans modifierL
Correction
Réponse : B. append() ajoute un élément à la fin de la liste. La liste est modifiée en place (pas de nouvelle liste créée).
- A est faux : l’insertion au début se fait avec
L.insert(0, 50), pas avecappend. - C est faux : l’insertion à une position arbitraire se fait avec
L.insert(i, val). - D est faux :
append()modifie la liste en place et renvoieNone.
4. Que produit le code [x * 2 for x in range(4)] ?
- A.
[0, 2, 4, 6] - B.
[2, 4, 6, 8] - C.
[0, 1, 2, 3] - D.
[0, 2, 4, 6, 8]
Correction
Réponse : A. range(4) produit 0, 1, 2, 3. On multiplie chaque valeur par 2 : 0, 2, 4, 6.
- B est faux :
range(4)commence à 0, pas à 1. Il faudraitrange(1, 5)pour obtenir[2, 4, 6, 8]. - C est faux : c’est le résultat de
[x for x in range(4)](sans la multiplication). - D est faux :
range(4)produit quatre valeurs, pas cinq. Erreur du « off-by-one ».
Exercice 2 : exemple travaillé – construire et parcourir une liste
Problème : on souhaite créer la liste des carrés des entiers de 1 à 5, puis afficher chaque élément avec son indice.
Étape 1. Créer la liste par compréhension :
carres = [n ** 2 for n in range(1, 6)]
print(carres) # [1, 4, 9, 16, 25]
Étape 2. Parcourir la liste avec les indices grâce à enumerate() :
for i, valeur in enumerate(carres):
print(f"carres[{i}] = {valeur}")
Résultat :
carres[0] = 1
carres[1] = 4
carres[2] = 9
carres[3] = 16
carres[4] = 25
Point clé : enumerate() renvoie à chaque tour un couple (indice, valeur), ce qui évite de gérer l’indice manuellement.
Exercice 3 : manipulations guidées
3.1 Création et accès
- Créer une liste
jourscontenant les sept jours de la semaine. - Afficher le troisième jour (attention à l’indexation).
- Remplacer
"dimanche"par"DIMANCHE". - Afficher la longueur de la liste.
Correction
jours = ["lundi", "mardi", "mercredi", "jeudi", "vendredi", "samedi", "dimanche"]
print(jours[2]) # "mercredi" (le 3e élément a l'indice 2)
jours[6] = "DIMANCHE" # ou jours[-1] = "DIMANCHE"
print(len(jours)) # 7
3.2 Construction par accumulation
Compléter le code suivant pour construire la liste des douze premiers nombres pairs (de 0 à 22) :
pairs = []
for i in range(___):
pairs.append(___)
print(pairs)
Correction
pairs = []
for i in range(12):
pairs.append(i * 2)
print(pairs) # [0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22]
Alternative par compréhension : pairs = [i * 2 for i in range(12)]
Exercice 4 : exercices progressifs
4.1 Classement sportif (sport)
Le classement d’une course est : ["Alice", "Bob", "Clara", "David", "Eva"].
- Afficher le(la) gagnant(e) (premier(ère) de la liste).
- Afficher le(la) dernier(ère) (sans connaître la taille de la liste à l’avance).
- Bob a été disqualifié. Le retirer de la liste avec
remove()et afficher le nouveau classement.
Correction
classement = ["Alice", "Bob", "Clara", "David", "Eva"]
print(f"Gagnant(e) : {classement[0]}") # Alice
print(f"Dernier(ère) : {classement[-1]}") # Eva
classement.remove("Bob")
print(classement) # ['Alice', 'Clara', 'David', 'Eva']
Point important : classement[-1] accède au dernier élément quelle que soit la longueur de la liste.
4.2 Liste de courses (vie courante)
Écrire un programme qui demande à l’utilisateur de saisir des articles un par un (en tapant "fin" pour arrêter), puis affiche la liste complète et le nombre total d’articles.
Correction
courses = []
while True:
article = input("Article (ou 'fin') : ")
if article == "fin":
break
courses.append(article)
print(f"Liste de courses ({len(courses)} articles) :")
for i, art in enumerate(courses, 1):
print(f" {i}. {art}")
4.3 Séparation pair/impair (mathématiques)
Écrire une fonction separer(L) qui prend une liste de nombres et renvoie deux listes : les nombres pairs et les nombres impairs.
print(separer([3, 8, 12, 5, 7, 20]))
# ([8, 12, 20], [3, 5, 7])
Correction
def separer(L):
pairs = []
impairs = []
for x in L:
if x % 2 == 0:
pairs.append(x)
else:
impairs.append(x)
return (pairs, impairs)
print(separer([3, 8, 12, 5, 7, 20]))
# ([8, 12, 20], [3, 5, 7])
Variante par compréhension :
def separer(L):
return ([x for x in L if x % 2 == 0],
[x for x in L if x % 2 != 0])
Exercice 5 : suppression des doublons
Écrire une fonction sans_doublons(L) qui prend une liste et renvoie une nouvelle liste contenant les mêmes éléments, dans le même ordre, mais sans les doublons.
print(sans_doublons([3, 1, 4, 1, 5, 9, 2, 6, 5, 3]))
# [3, 1, 4, 5, 9, 2, 6]
Indication : parcourir la liste et n’ajouter un élément à la nouvelle liste que s’il n’y figure pas déjà (tester avec not in).
Correction
def sans_doublons(L):
resultat = []
for x in L:
if x not in resultat:
resultat.append(x)
return resultat
print(sans_doublons([3, 1, 4, 1, 5, 9, 2, 6, 5, 3]))
# [3, 1, 4, 5, 9, 2, 6]
Remarque : l’opérateur not in parcourt toute la liste resultat à chaque test, ce qui rend la complexité quadratique ($O(n^2)$) dans le pire cas. Pour de grandes listes, on utiliserait un ensemble (set).
Exercice 6 : synthèse – relevé de températures (géographie)
On dispose du relevé de températures (en °C) d’une semaine : [12.5, 14.0, 11.3, 15.8, 13.2, 9.7, 16.1].
- Écrire une fonction
moyenne(L)qui calcule la moyenne d’une liste de nombres. - Écrire une fonction
au_dessus(L, seuil)qui renvoie la liste des températures strictement supérieures au seuil donné. - Écrire une fonction
indice_max(L)qui renvoie l’indice de la valeur maximale (sans utilisermax()niindex()). - Utiliser ces fonctions pour afficher la température moyenne de la semaine, les jours où il a fait plus de 14 °C et le jour le plus chaud.
Correction
def moyenne(L):
return sum(L) / len(L)
def au_dessus(L, seuil):
return [x for x in L if x > seuil]
def indice_max(L):
i_max = 0
for i in range(1, len(L)):
if L[i] > L[i_max]:
i_max = i
return i_max
temps = [12.5, 14.0, 11.3, 15.8, 13.2, 9.7, 16.1]
jours = ["lundi", "mardi", "mercredi", "jeudi", "vendredi", "samedi", "dimanche"]
print(f"Moyenne : {round(moyenne(temps), 1)} °C")
print(f"Jours > 14 °C : {au_dessus(temps, 14)}")
i = indice_max(temps)
print(f"Jour le plus chaud : {jours[i]} ({temps[i]} °C)")
Résultat :
Moyenne : 13.2 °C
Jours > 14 °C : [14.0, 15.8, 16.1]
Jour le plus chaud : dimanche (16.1 °C)
Exercice 7 : effets de bord
- Prévoir l’affichage du programme suivant, puis vérifier.
def retirer_premier(L):
L.pop(0)
def sans_premier(L):
return L[1:]
a = [3, 6, 9]
b = sans_premier(a)
print(a, b)
retirer_premier(a)
print(a, b)
- Laquelle des deux fonctions a un effet de bord ? À quoi le voit-on dans son code ?
- Écrire une fonction
plafonner(L, m)qui remplace, dans la listeLelle-même, chaque valeur strictement supérieure àmparm, et ne renvoie rien. Écrire ensuite une fonctionplafonnee(L, m)qui renvoie une nouvelle liste plafonnée et laisseLintacte.
Correction
- Affichage :
[3, 6, 9] [6, 9]
[6, 9] [6, 9]
sans_premier construit une nouvelle liste par slicing : a n’est pas modifiée. retirer_premier appelle pop sur la liste reçue, qui est a elle-même : après l’appel, a a perdu son premier élément. b, liste distincte, ne change pas.
retirer_premiera un effet de bord : elle appelle une méthode qui modifie la liste (pop) et ne renvoie rien.sans_premierne modifie rien et renvoie un résultat.Les deux versions :
def plafonner(L, m):
"""Remplace dans L chaque valeur > m par m. Modifie L, ne renvoie rien."""
for i in range(len(L)):
if L[i] > m:
L[i] = m
def plafonnee(L, m):
"""Renvoie une nouvelle liste plafonnée à m ; L n'est pas modifiée."""
resultat = []
for x in L:
if x > m:
resultat.append(m)
else:
resultat.append(x)
return resultat
notes = [8, 21, 15, 23]
print(plafonnee(notes, 20), notes) # [8, 20, 15, 20] [8, 21, 15, 23]
plafonner(notes, 20)
print(notes) # [8, 20, 15, 20]
Exercice 8 : compréhensions de listes
Écrire chacune des listes suivantes en une seule instruction, par compréhension.
- Les entiers de 0 à 10.
- Les carrés des entiers de 0 à 10.
- Les entiers pairs de 0 à 20.
- À partir de
mots = ["chat", "girafe", "python", "oie", "hérisson"], les mots d’au moins six caractères, écrits en majuscules. - À partir de
nombres = [4, -2, 7, 0, -9, 3], les nombres strictement positifs. - À partir de
matrice = [[1, 2, 3], [4, 5, 6]], la liste « aplatie »[1, 2, 3, 4, 5, 6].
Correction
mots = ["chat", "girafe", "python", "oie", "hérisson"]
nombres = [4, -2, 7, 0, -9, 3]
matrice = [[1, 2, 3], [4, 5, 6]]
print([i for i in range(11)]) # [0, 1, ..., 10]
print([i ** 2 for i in range(11)]) # [0, 1, 4, ..., 100]
print([i for i in range(0, 21, 2)]) # [0, 2, 4, ..., 20]
print([m.upper() for m in mots if len(m) >= 6]) # ['GIRAFE', 'PYTHON', 'HÉRISSON']
print([x for x in nombres if x > 0]) # [4, 7, 3]
print([x for ligne in matrice for x in ligne]) # [1, 2, 3, 4, 5, 6]
Pour la dernière, les deux for se lisent dans l’ordre des boucles imbriquées : pour chaque ligne de la matrice, pour chaque x de la ligne.