Vue d'ensemble
La liste est la structure de données que tu utiliseras le plus en prépa : dès qu'il faut ranger plusieurs valeurs (des notes, des mesures, les termes d'une suite, les pixels d'une image), c'est une liste. Une liste est une collection ordonnée de valeurs, repérées par leur position (l'indice), et surtout elle est modifiable : on peut changer un élément, en ajouter, en retirer, sans repartir de zéro.
Cette fiche te donne tous les gestes de base — créer, accéder, modifier, ajouter, retirer, trier,
découper, copier — décryptés ligne par ligne, avec les pièges qui font perdre des
points en début d'année (l'alias qui n'est pas une copie, sort() qui renvoie None…).
Prérequis
- Savoir affecter une variable et connaître les types de base (
int,str…) - Connaître
rangeet le principe d'une bouclefor(utile mais pas indispensable)
Les listes sont le socle de tout le programme d'info. Si les indices, les copies et la mutabilité restent flous, chaque TP devient un chemin de croix. Nos mentors alumni X · Centrale · Mines remettent ces automatismes en place avec toi, à ton rythme, avant que le programme ne s'accélère.
Trouver un mentor →1. Créer une liste
Une liste est une suite ordonnée de valeurs, écrite entre crochets et séparée par des virgules. Les valeurs peuvent être de n'importe quel type (et même de types différents), mais en pratique on manipule surtout des listes homogènes (que des entiers, que des chaînes…).
notes = [12, 15, 8, 17] # liste de 4 entiers
vide = [] # liste vide (0 élément)
zeros = [0] * 5 # [0, 0, 0, 0, 0]
compteur = list(range(1, 6)) # [1, 2, 3, 4, 5]notes = [12, 15, 8, 17]Littéral. Les crochets créent une liste directement à partir des valeurs listées. Ici 4 éléments, dans cet ordre.vide = []Liste vide. Des crochets sans rien dedans : une liste de longueur 0. C'est le point de départ classique quand on veut remplir une liste petit à petit avec append.zeros = [0] * 5Répétition. * 5 répète le contenu 5 fois : on obtient une liste de 5 zéros. Idéal pour préparer un tableau qu'on remplira ensuite.list(range(1, 6))À partir d'un range. range(1, 6) engendre 1, 2, 3, 4, 5 (la borne 6 est exclue) ; list(...) les rassemble dans une vraie liste.range(a, b) parcourt
a, a+1, …, b-1. Donc list(range(0, 5)) donne
[0, 1, 2, 3, 4] : 5 éléments, mais le 5 n'y est pas.
2. Accéder et modifier un élément
Chaque élément a une position appelée indice. Point crucial : on compte à partir de 0. Le premier élément est à l'indice 0, le deuxième à l'indice 1, etc.
| Élément | 12 | 15 | 8 | 17 |
|---|---|---|---|---|
| Indice positif | 0 | 1 | 2 | 3 |
| Indice négatif | -4 | -3 | -2 | -1 |
notes = [12, 15, 8, 17]
notes[0] # 12 : premier élément
notes[2] # 8 : troisième élément
notes[-1] # 17 : dernier élément
notes[1] = 20 # on remplace 15 par 20 -> [12, 20, 8, 17]notes[0]Indexation depuis 0. L'indice 0 donne le premier élément, ici 12. Une source d'erreurs classique quand on débute.notes[-1]Indice négatif. Les indices négatifs comptent depuis la fin : -1 est le dernier, -2 l'avant-dernier. Très pratique pour lire la fin sans connaître la longueur.notes[1] = 20Modification en place. On écrit dans la case d'indice 1 : la liste devient [12, 20, 8, 17]. C'est possible parce qu'une liste est mutable.
Un objet est mutable si on peut le modifier après sa création. Les listes sont mutables :
liste[i] = ... change réellement la liste existante, on ne crée pas une nouvelle liste. (À
l'inverse, les entiers et les chaînes sont immuables : on ne peut pas modifier un caractère
d'une chaîne par s[0] = "A".)
notes[4] déclenche une IndexError: list index out of range.
Le dernier indice valide est toujours len(liste) - 1.
3. Ajouter et retirer des éléments
C'est ici que la mutabilité prend tout son sens : on fait grandir ou rétrécir la liste en place.
t = [10, 20, 30]
t.append(40) # ajoute 40 à la FIN -> [10, 20, 30, 40]
t.insert(1, 15) # insère 15 à l'indice 1 -> [10, 15, 20, 30, 40]
dernier = t.pop()# retire et renvoie le dernier (40) -> [10, 15, 20, 30]
del t[0] # supprime l'élément d'indice 0 -> [15, 20, 30]
t.remove(20) # retire la 1re occurrence de 20 -> [15, 30]t.append(40)Ajout à la fin. append allonge la liste d'un élément, tout à droite. C'est LA méthode pour construire une liste au fil d'une boucle.t.insert(1, 15)Insertion à une position. insert(i, x) place x à l'indice i et décale les suivants vers la droite. Ici 15 s'intercale entre 10 et 20.dernier = t.pop()Retirer ET récupérer. pop() enlève le dernier élément et renvoie sa valeur (ici 40, rangée dans dernier). On peut viser un indice précis : t.pop(0) retire le premier.del t[0]Supprimer par indice. del retire l'élément à la position donnée, sans renvoyer sa valeur.t.remove(20)Supprimer par valeur. remove(x) cherche x et retire sa première occurrence. Si x est absent, ça déclenche une ValueError.append(x) revient exactement à
insert(len(liste), x) : ajouter à la fin. Mais append est plus clair et
plus rapide — utilise-le dès que tu ajoutes à la fin.
append.
carres = []
for x in range(5):
carres.append(x * x)
# carres vaut [0, 1, 4, 9, 16]4. Fonctions et méthodes utiles
Python fournit des outils tout prêts pour interroger une liste sans écrire de boucle.
| Écriture | Rôle | Résultat |
|---|---|---|
len(v) | nombre d'éléments | 5 |
sum(v) | somme des éléments | 27 |
min(v) | plus petit | 2 |
max(v) | plus grand | 8 |
8 in v | présence d'une valeur | True |
v.count(8) | nombre d'occurrences | 2 |
v.index(8) | indice de la 1re occurrence | 1 |
x in v renvoie un booléen (pratique dans un if).
v.index(x) renvoie la position, mais déclenche une ValueError si x
est absent — teste if x in v: avant, en cas de doute.
Trier une liste : sorted vs sort
Deux façons de trier — et c'est un piège d'examen classique de les confondre.
v = [4, 8, 2, 8, 5]
w = sorted(v) # w vaut [2, 4, 5, 8, 8] ; v est INCHANGÉE
v.sort() # v devient [2, 4, 5, 8, 8] ; sort() renvoie None
sorted(v, reverse=True) # [8, 8, 5, 4, 2] : ordre décroissantsorted(v)Renvoie une NOUVELLE liste triée. La liste d'origine v n'est pas touchée. On récupère le résultat dans une variable (w = sorted(v)).v.sort()Trie EN PLACE. La méthode réorganise v elle-même et renvoie None. On ne l'affecte donc jamais à une variable.sorted(v, reverse=True)Option decroissant. L'argument reverse=True marche pour les deux (sorted comme .sort()).5. Slicing et copie
Le slicing (tranche) extrait un morceau de liste avec la syntaxe
liste[a:b] : les éléments d'indice a inclus à b exclu.
Comme range, la borne de droite est exclue.
s = [10, 11, 12, 13, 14, 15]
s[1:4] # [11, 12, 13] : indices 1, 2, 3 (4 exclu)
s[:3] # [10, 11, 12] : depuis le début
s[3:] # [13, 14, 15] : jusqu'à la fin
s[::2] # [10, 12, 14] : un élément sur deux (pas = 2)
s[::-1] # [15, 14, 13, 12, 11, 10] : liste inversées[1:4]Tranche a:b. On garde les indices 1, 2, 3 — l'indice 4 est exclu, exactement comme range.s[:3]Borne omise. Sans début, la tranche part de 0 ; sans fin, elle va jusqu'au bout. s[:3] = les trois premiers.s[::2]Le pas. Le troisième nombre est le pas : 2 prend un élément sur deux.s[::-1]Pas négatif. Un pas de -1 parcourt la liste à l'envers : c'est l'astuce pour l'inverser.| Écriture | Effet |
|---|---|
b = a | PAS une copie : b est un autre nom pour la même liste |
b = a[:] | vraie copie indépendante (tranche complète) |
b = list(a) | vraie copie indépendante (reconstruction) |
La copie de liste est le piège n°1 des débutants — et il revient à chaque colle. Si tu veux t'entraîner sur des vrais sujets, encadré par des alumni X · Centrale · Mines qui ont passé ces épreuves, un stage intensif Majorant te met les automatismes en place en quelques jours.
Découvrir les stages →6. Compréhensions de listes
Une compréhension est un raccourci pour construire une liste en une seule ligne,
à la place d'une boucle avec append. C'est très pratique une fois qu'on l'a comprise.
carres = [x * x for x in range(5)] # [0, 1, 4, 9, 16]
positifs = [x for x in [3, -1, 4, -2] if x > 0] # [3, 4][x * x for x in range(5)]Transformer chaque élément. Ça se lit « x * x, pour chaque x de range(5) ». Équivaut exactement à la boucle carres = [] puis append vue en section 3.[x for x in liste if x > 0]Filtrer. Le if à la fin ne garde que les éléments qui vérifient la condition. Ici, on ne conserve que les nombres strictement positifs.for avec append le fait aussi. Utilise-la quand elle rend le code plus lisible ;
en cas de doute, une boucle classique reste parfaitement correcte.
7. Erreurs classiques (les pièges qui coûtent des points)
Ces quatre erreurs reviennent sans cesse en début d'année. Repère-les maintenant.
b = a n'est pas une copie. Après b = a, les deux
noms désignent la même liste. Donc b.append(99) modifie aussi a !
Pour une vraie copie indépendante, écris b = a[:] ou b = list(a).
a = [1, 2, 3]
b = a
b.append(99)
print(a) # [1, 2, 3, 99] <- a a changé aussi !liste = liste.sort() écrase ta liste avec None.
Comme sort() trie en place et renvoie None, l'affectation range None
dans liste : tu perds tout. Écris liste.sort() seul, ou
liste = sorted(liste).
v = [3, 1, 2]
v = v.sort() # PIÈGE : v vaut maintenant None
print(v) # Nonefor sur cette même liste décale les indices et fait sauter des éléments. Parcours
plutôt une copie (for x in liste[:]:), ou construis une nouvelle liste avec une
compréhension filtrante.
n, les indices
valides vont de 0 à n - 1. liste[n] ou liste[len(liste)] déclenche
toujours une IndexError. Le dernier élément est liste[-1] ou
liste[len(liste) - 1].
8. Pour aller plus loin
Une fois ces gestes acquis, les listes deviennent le support de presque tous les algorithmes du programme. Voici les chapitres qui réinvestissent directement ce que tu viens de voir :
- Patrons algorithmiques sur les listes — parcourir, chercher un maximum, compter, accumuler : les schémas de boucle standards.
- Tableaux 2D et images — les listes de listes, pour représenter une grille ou une image en pixels.
- Tri par insertion et par sélection — comprendre comment on trie « à la main », derrière la magie de
sort().
9. Exercices d'application
À faire de tête, puis à vérifier en machine avant d'ouvrir le corrigé.
Écris deux versions qui construisent la liste des carrés des entiers de 0 à n inclus : une avec une boucle et append, une avec une compréhension. Pour n = 4, on attend [0, 1, 4, 9, 16].
Voir la correction détaillée
carres = [] puis for x in range(n + 1): carres.append(x * x). Le + 1 est indispensable pour inclure n, car range exclut sa borne de droite.carres = [x * x for x in range(n + 1)] — même résultat, une seule ligne.n = 4, range(5) donne 0, 1, 2, 3, 4 et les carrés [0, 1, 4, 9, 16].À partir de v = [7, 4, 10, 3, 8], construis la liste des éléments pairs, sans modifier v. Résultat attendu : [4, 10, 8].
v = [7, 4, 10, 3, 8]
# construis pairs = [4, 10, 8]Voir la correction détaillée
x % 2 == 0.pairs = [x for x in v if x % 2 == 0]. On parcourt v et on ne garde que les x pairs.v reste [7, 4, 10, 3, 8] — c'est bien ce qui est demandé. Le piège serait de retirer les impairs en parcourant v directement.pairs = [] puis for x in v: if x % 2 == 0: pairs.append(x).Récap final — Ce qu'il faut absolument retenir
Tu dois pouvoir répondre « oui » sans hésiter à chaque point.
- Sais-tu créer une liste vide, une liste de
nzéros ([0] * n), une liste à partir d'unrange? - Sais-tu que l'indexation commence à 0 et que
liste[-1]est le dernier élément ? - Sais-tu expliquer pourquoi
liste[i] = ...fonctionne (une liste est mutable) ? - Sais-tu ce que fait
append,insert,pop,deletremove? - Sais-tu que
pop()retire et renvoie le dernier élément ? - Sais-tu utiliser
len,sum,min,max,in,countetindex? - Sais-tu que
sorted(v)renvoie une nouvelle liste triée sans toucherv? - Sais-tu que
v.sort()trie en place et renvoieNone(donc on ne l'affecte jamais) ? - Sais-tu extraire une tranche
liste[a:b](bornebexclue) et inverser avec[::-1]? - Sais-tu faire une vraie copie avec
a[:]oulist(a), et pourquoib = an'en est pas une ? - Sais-tu écrire une compréhension pour transformer (
[x*x for x in ...]) et pour filtrer (... if ...) ? - Repères-tu le dernier indice valide (
len(liste) - 1) pour éviter l'IndexError?