Les Listes en Python
Creer une liste
Une liste est une collection ordonnee et modifiable d'elements. En Python, les listes peuvent contenir des elements de types differents.
# Liste vide
vide = []
aussi_vide = list()
# Liste de nombres
notes = [15, 12, 18, 9, 14]
# Liste de chaines
fruits = ["pomme", "banane", "cerise"]
# Liste mixte (possible mais rarement utile)
melange = [42, "bonjour", True, 3.14]
# A partir d'un range
cinq_premiers = list(range(5)) # [0, 1, 2, 3, 4]
pairs = list(range(0, 10, 2)) # [0, 2, 4, 6, 8]
Acceder aux elements
Indexation positive
Les elements sont indexes a partir de 0 :
fruits = ["pomme", "banane", "cerise", "datte"]
print(fruits[0]) # pomme (premier)
print(fruits[1]) # banane
print(fruits[2]) # cerise
print(fruits[3]) # datte (dernier, index = longueur - 1)
Indexation negative
Les indices negatifs partent de la fin : -1 est le dernier element, -2 l'avant-dernier, etc.
fruits = ["pomme", "banane", "cerise", "datte"]
print(fruits[-1]) # datte (dernier)
print(fruits[-2]) # cerise (avant-dernier)
print(fruits[-4]) # pomme (premier depuis la fin)
Slicing (decoupage)
Le slicing permet d'extraire une sous-liste avec la syntaxe liste[debut:fin:pas]. La borne fin est exclue.
nombres = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
print(nombres[2:5]) # [2, 3, 4] (indices 2, 3, 4)
print(nombres[:4]) # [0, 1, 2, 3] (du debut a l'index 3)
print(nombres[6:]) # [6, 7, 8, 9] (de l'index 6 a la fin)
print(nombres[::2]) # [0, 2, 4, 6, 8] (un sur deux)
print(nombres[1::2]) # [1, 3, 5, 7, 9] (impairs)
print(nombres[::-1]) # [9, 8, 7, 6, 5, 4, 3, 2, 1, 0] (inverse)
print(nombres[2:8:3]) # [2, 5] (de 2 a 7, pas de 3)
Modifier une liste
Les listes sont mutables : on peut changer leurs elements directement.
notes = [12, 15, 9, 18, 11]
# Modifier un element
notes[2] = 14
print(notes) # [12, 15, 14, 18, 11]
# Modifier une plage (slice)
notes[1:3] = [17, 16]
print(notes) # [12, 17, 16, 18, 11]
Methodes des listes
Python fournit de nombreuses methodes pour manipuler les listes.
Ajouter des elements
fruits = ["pomme", "banane"]
fruits.append("cerise") # ajoute a la fin
print(fruits) # ["pomme", "banane", "cerise"]
fruits.insert(1, "abricot") # insere a l'index 1
print(fruits) # ["pomme", "abricot", "banane", "cerise"]
fruits.extend(["datte", "figue"]) # ajoute plusieurs elements
print(fruits) # ["pomme", "abricot", "banane", "cerise", "datte", "figue"]
Supprimer des elements
fruits = ["pomme", "banane", "cerise", "banane"]
fruits.remove("banane") # supprime la PREMIERE occurrence
print(fruits) # ["pomme", "cerise", "banane"]
dernier = fruits.pop() # supprime et retourne le dernier
print(dernier) # "banane"
print(fruits) # ["pomme", "cerise"]
deuxieme = fruits.pop(0) # supprime et retourne l'element a l'index 0
print(deuxieme) # "pomme"
fruits.clear() # vide completement la liste
print(fruits) # []
Trier et inverser
nombres = [3, 1, 4, 1, 5, 9, 2, 6]
nombres.sort() # tri en place (modifie la liste)
print(nombres) # [1, 1, 2, 3, 4, 5, 6, 9]
nombres.sort(reverse=True) # tri inverse
print(nombres) # [9, 6, 5, 4, 3, 2, 1, 1]
nombres.reverse() # inverse l'ordre en place
print(nombres) # [1, 1, 2, 3, 4, 5, 6, 9]
Rechercher
fruits = ["pomme", "banane", "cerise", "banane"]
idx = fruits.index("banane") # indice de la PREMIERE occurrence
print(idx) # 1
nb = fruits.count("banane") # nombre d'occurrences
print(nb) # 2
Copier
original = [1, 2, 3]
copie = original.copy() # copie superficielle
copie.append(4)
print(original) # [1, 2, 3] (non modifie)
print(copie) # [1, 2, 3, 4]
Fonctions built-in pour les listes
notes = [12, 15, 9, 18, 11, 14]
print(len(notes)) # 6 - nombre d'elements
print(min(notes)) # 9 - valeur minimale
print(max(notes)) # 18 - valeur maximale
print(sum(notes)) # 79 - somme des elements
moyenne = sum(notes) / len(notes)
print(round(moyenne, 2)) # 13.17
Listes en comprehension
Les listes en comprehension permettent de creer des listes de maniere concise et lisible.
# Syntaxe : [expression for element in iterable if condition]
# Sans condition
carres = [x ** 2 for x in range(6)]
print(carres) # [0, 1, 4, 9, 16, 25]
# Avec condition
pairs = [x for x in range(10) if x % 2 == 0]
print(pairs) # [0, 2, 4, 6, 8]
# Transformation de chaines
noms = ["alice", "bob", "claire"]
majuscules = [nom.upper() for nom in noms]
print(majuscules) # ["ALICE", "BOB", "CLAIRE"]
# Filtrer et transformer
notes = [12, 15, 9, 18, 11, 14]
bonnes_notes = [n for n in notes if n >= 12]
print(bonnes_notes) # [12, 15, 18, 14]
Comparaison avec la boucle equivalente :
# Avec boucle
carres = []
for x in range(6):
carres.append(x ** 2)
# Avec comprehension (equivalent, plus concis)
carres = [x ** 2 for x in range(6)]
Listes imbriquees (matrices 2D)
Une liste peut contenir d'autres listes, ce qui permet de representer des matrices ou des tableaux 2D :
matrice = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
]
# Acces : matrice[ligne][colonne]
print(matrice[0][0]) # 1 (ligne 0, colonne 0)
print(matrice[1][2]) # 6 (ligne 1, colonne 2)
print(matrice[2][1]) # 8 (ligne 2, colonne 1)
# Parcourir une matrice
for ligne in matrice:
for valeur in ligne:
print(valeur, end=" ")
print()
# 1 2 3
# 4 5 6
# 7 8 9
Decomposition (unpacking)
On peut "decompacter" une liste en plusieurs variables :
coordonnees = [48.8566, 2.3522]
latitude, longitude = coordonnees
print(latitude) # 48.8566
print(longitude) # 2.3522
# Unpacking avec *rest
nombres = [1, 2, 3, 4, 5]
premier, *reste = nombres
print(premier) # 1
print(reste) # [2, 3, 4, 5]
*debut, dernier = nombres
print(debut) # [1, 2, 3, 4]
print(dernier) # 5
premier, *milieu, dernier = nombres
print(premier) # 1
print(milieu) # [2, 3, 4]
print(dernier) # 5
Verifier l'appartenance
fruits = ["pomme", "banane", "cerise"]
print("banane" in fruits) # True
print("mangue" in fruits) # False
print("mangue" not in fruits) # True
# Utilisation dans un if
if "cerise" in fruits:
print("On a des cerises !")
Copie superficielle vs copie profonde
Attention a la copie des listes imbriquees :
import copy
# Assignation : pas une copie !
a = [1, 2, 3]
b = a # b pointe vers le MEME objet
b.append(4)
print(a) # [1, 2, 3, 4] (a aussi modifie !)
# Copie superficielle : OK pour listes simples
a = [1, 2, 3]
b = a.copy() # ou b = a[:] ou b = list(a)
b.append(4)
print(a) # [1, 2, 3] (a non modifie)
# Copie superficielle INSUFFISANTE pour listes imbriquees
a = [[1, 2], [3, 4]]
b = a.copy()
b[0].append(99)
print(a) # [[1, 2, 99], [3, 4]] (a aussi modifie !)
# Copie profonde : independance totale
a = [[1, 2], [3, 4]]
b = copy.deepcopy(a)
b[0].append(99)
print(a) # [[1, 2], [3, 4]] (a non modifie)
Trier avec une cle personnalisee
sorted() retourne une nouvelle liste triee sans modifier l'originale. Le parametre key accepte une fonction :
etudiants = [("Alice", 17), ("Bob", 15), ("Claire", 19), ("David", 16)]
# Trier par note (index 1)
par_note = sorted(etudiants, key=lambda e: e[1])
print(par_note)
# [('Bob', 15), ('David', 16), ('Alice', 17), ('Claire', 19)]
# Trier par nom (index 0)
par_nom = sorted(etudiants, key=lambda e: e[0])
print(par_nom)
# [('Alice', 17), ('Bob', 15), ('Claire', 19), ('David', 16)]
# Trier des chaines sans tenir compte de la casse
mots = ["Banane", "abricot", "Cerise", "datte"]
tries = sorted(mots, key=lambda m: m.lower())
print(tries) # ['abricot', 'Banane', 'Cerise', 'datte']
Exercices pratiques
Exercice 1 : Creer une liste et acceder aux elements
Utilisez liste[-1] plutot que liste[len(liste)-1] pour acceder au dernier element. C'est plus lisible et moins sujet aux erreurs. De meme, liste[-2] pour l'avant-dernier est idiomatique en Python.
Exercice 2 : Modifier une liste avec append et pop
pop(0) sur une liste est lent (O(n)) car Python doit decaler tous les elements. Si vous utilisez frequemment des ajouts/suppressions en debut de liste, utilisez collections.deque qui est optimise pour ca (O(1)).
Exercice 3 : Slicing
Rappelez-vous que liste[debut:fin] inclut debut mais exclut fin. Pour copier une liste entiere, liste[:] est un raccourci pratique. Le slice [::-1] est la facon pythonique d'inverser une liste (ou une chaine).
Exercice 4 : Liste en comprehension (carres)
Les listes en comprehension sont excellentes pour des transformations simples. Si votre comprehension devient trop longue ou complexe (plus d'une condition, plusieurs boucles imbriquees), preferez une boucle for classique pour la lisibilite. La regle : si ca ne tient pas sur une ligne claire, utilisez une boucle.
Exercice 5 : Trier une liste
Utilisez sort() (methode, modifie en place) quand vous n'avez plus besoin de l'ordre original. Utilisez sorted() (fonction built-in) quand vous voulez conserver la liste originale ou trier un iterable quelconque. sorted() retourne toujours une nouvelle liste.
Exercice 6 : Trouver un element avec index()
index() leve une ValueError si l'element n'est pas trouve. Avant d'appeler index(), verifiez d'abord la presence avec if valeur in liste. Alternativement, utilisez un bloc try/except ValueError pour gerer le cas ou l'element est absent.
Quiz de revision
Une solution
Vous devez être connecté pour voir le contenu.