Les listes
Une liste est un objet pouvant en contenir d’autres (de tout type), organisés séquentiellement (les uns à la suite des autres).
Accès aux éléments d’une liste
Une liste est ordonnée : on accède à ses éléments en indiquant leur indice (index en anglais).
>>> liste = [] # Une liste vide >>> liste [] >>> liste = [1, 'deux', 3, 'quatre', 5, 6] # Une liste qui contient différents types d'objets >>> liste [1, 'deux', 3, 'quatre', 5, 6] >>> liste[2] # Accès au 3ième (indice 2) élément de la liste 3 >>> len(liste) # nombre d’éléments dans la liste 6 >>> liste[6] # la liste n'a pas d'élément d'indice 6 ! Traceback (most recent call last): File "<stdin>", line 1, in <module> IndexError: list index out of range
ATTENTION : il ne faut pas nommer la variable list , sous peine de « cacher » l’instruction Python list() : le nom list ferait alors référence à la variable list et plus à la fonction list() , qui ne serait plus disponible, tant qu’on n’aurait pas détruit la variable list par l’instruction del list .
Liste = objet muable
Les listes sont des objets muables (mutable en anglais).
objet immuable
>>> x = 3.2 >>> y = x >>> y +=1 >>> y 4.2 >>> x 3.2 >>> id(x), id(y) (36418024, 36418012) # 2 objets différents ! |
objet muable
>>> x = [4,2,5] >>> y = x >>> y += [3,9] >>> y [4, 2, 5, 3, 9] >>> x [4, 2, 5, 3, 9] >>> id(x), id(y) (4494886456, 4494886456) # un seul et même objet ! |
Exercice :
Prédire (AVANT d’utiliser Python) les valeurs de lst1 et lst2 après le suite d’instructions suivante :
>>> lst1 = ['a', 'b', 'c'] >>> lst2 = lst1+['d'] >>> lst1[0] += 'z'
Découpage ou Slicing
Le slicing (saucissonage) permet d’obtenir une sous-liste depuis une liste.
La syntaxe est la suivante (en gros 7 possibilités) :
liste[debut:fin:pas] liste[debut:fin] liste[debut:] liste[:fin] liste[::pas] liste[debut::pas] liste[:fin:pas]
- debut : indice du premier éléments à sélectionner (par défaut : le premier élément de la liste)
- fin : indice du dernier élément exclu à sélectionner (par défaut : le dernier élément de la liste)
- pas : 1 par défaut
Pour extraire une sous-liste, il faut imaginer que les indices représentent non pas les tranches de saucisson, mais les coups de couteau qui vont permettre de couper les tranches (en partant de 0 pour l’entame).
Ainsi :
>>> liste[1:4] ['deux', 3, 'quatre']
Exercices :
- Tester les instructions suivantes :
>>> liste[:2] >>> liste[0:len(liste)] >>> liste[:] >>> liste[2:5] >>> liste[2:7] >>> liste[-2:-4] >>> liste[-4:-2] >>> liste[-2] >>> liste[-1]
- Écrire une instruction qui permet d’obtenir la liste inverse d’une liste, uniquement par slicing.
Créer une liste
par la fonction range()
>>> range(9) range(0,9) >>> type(range(9)) <class 'range'>
Remarque : depuis la version 3 de Python, la fonction range() renvoie un objet de type range (un itérateur) , et non une liste. Pour afficher son contenu, on peut le convertir en liste, grâce à l’instruction list() :
>>> list(range(9)) [0, 1, 2, 3, 4, 5, 6, 7, 8] >>> list(range(2, 60, 10)) # comme pour le « slicing » [2, 12, 22, 32, 42, 52]
par compréhension
>>> [chr(n+65) for n in range(10)] ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J'] >>> [n for n in range(1,50) if n%3==0] [3, 6, 9, 12, 15, 18, 21, 24, 27, 30, 33, 36, 39, 42, 45, 48] >>> [c for c in "c'est Fantastique"] ["c","'","e","s","t"," ","F","a","n","t","a","s","t","i","q","u","e"]
Remarque : pour des détails sur la structure for…in… , voir la page les boucles.
Modifier une liste
par opérations
Deux opérateurs sont reconnus :
- l’addition de deux listes : liste1 + liste2
- la multiplication par un entier : liste * entier
>>> ['a']*12 ['a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a'] >>> (["L'informatique"]+["c'est"]+["Fantastique"])*2 ["L'informatique", "c'est", "Fantastique", "L'informatique", "c'est", "Fantastique"]
par ajout d’éléments
- ajout à la fin :
>>> l = ['riri', 'fifi'] >>> l.append('loulou') >>> l ['riri', 'fifi', 'loulou']
- insertion :
>>> l.insert(1, 'Donald') >>> l ['riri', 'Donald', 'fifi', 'loulou']
par remplacement d’éléments
>>> l[1] = 'Picsou' >>> l ['riri', 'Picsou', 'fifi', 'loulou']
On peut également remplacer une portion entière de la liste, en utilisant le slicing :
>>> l[2:] = ['Daisy', 'Horace', 'Pluto'] >>> l ['riri', 'Picsou', 'Daisy', 'Horace', 'Pluto']
par suppression d’éléments
>>> del l[1] >>> l ['riri', 'Daisy', 'Horace', 'Pluto']
Ou également grâce à la méthode .remove() :
>>> l.remove('Pluto') >>> l ['riri', 'Daisy', 'Horace']
Copier une liste
par « slicing »
>>> nliste1 = liste[:] >>> id(nliste1), id(liste) (44948542180, 4494886456) # deux objets différents
avec le constructeur list()
>>> nliste2 = list(liste) [1, 'deux', 3, 'quatre', 5, 6]
Trier une liste
Tri sur place
>>> nliste1.sort() ; nliste1 [1, 3, 5, 6, 'deux', 'quatre'] # c'est le même objet de type list, mais ordonnée.
Tri avec copie
>>> sorted(liste) [1, 3, 5, 6, 'deux', 'quatre'] # c'est un autre objet list : l'original existe toujours
Les fonctions de tri peuvent admettre un deuxième argument key qui spécifie une fonction à un seul argument fournissant une clef de comparaison de la liste à trier.
Par exemple, pour trier une liste de tuples selon leur élément d’indice 1 :
>>> sorted([(1, 'b'), (3, 'a'), (2, 'c')], key = lambda x: x[1]) [(3, 'a'), (1, 'b'), (2, 'c')] >>> sorted([(1, 'b'), (3, 'a'), (2, 'c')]) # par défaut, les tuples sont triés selon la valeur de leur 1er élément [(1, 'b'), (2, 'c'), (3, 'a')]
Remarque : f = lambda x: x**2 est l’équivalent Python de $f:x \rightarrow x^2$
Exercices :
La liste suivante contient les résultats de plusieurs lancés de 2 dés (c’est une liste de listes) :
l = [[1,5], [2,3], [6,4], [5,6], [3,2], [4,1], [2,5]]
Trier cette liste dans l’ordre décroissant de la somme des deux dés, grâce à l’instruction sorted() et en utilisant son argument key .
Inverser une liste
>>> nliste1.reverse() ; nliste1 ['quatre', 'deux', 6, 5, 3, 1] >>> nliste1[::-1] [1, 3, 5, 6, 'deux', 'quatre']
(Dé)Zipper une liste
Le « zippage » est une opération qui permet de combiner deux listes de même taille. La fonction zip() opère en quelque sorte une transposition de tableau (si on considère qu’un tableau est une liste de listes !) :
>>> Simpson = ['Homer', 'Marge', 'Bart', 'Lisa'] >>> Famille = ['père', 'mère', 'fils', 'fille'] >>> Famille_Simpson = list(zip(Famille, Simpson)) # zippage ! (résultat converti en liste pour affichage) >>> Famille_Simpson [('père', 'Homer'), ('mère', 'Marge'), ('fils', 'Bart'), ('fille', 'Lisa')] >>> list(zip(*Famille_Simpson)) # dézippage ! [('père', 'mère', 'fils', 'fille'), ('Homer', 'Marge', 'Bart', 'Lisa')]
Chercher un élément dans une liste
La méthode .index() permet d’obtenir l’indice d’un élément contenu dans une liste.
>>> Simpson = ['Homer', 'Marge', 'Bart', 'Lisa'] >>> Simpson.index('Bart') 2
Attention :
- Si l’élément recherché n’est pas dans la liste, .index() renvoie un message d’erreur.
Il faudra donc tester l’appartenance de l’élément à la liste avant d’appeler .index() (voir page structures conditionnelles), ou bien intercepter l’erreur pour éviter que l’exécution du programme ne s’arrête (voir structure try … except … ).
- S’il existe plusieurs éléments identiques dans la liste, seul l’indice du premier sera renvoyé.
Exercices
- Générer, en une seule instruction, la liste des boules numérotées du Loto.
- Écrire une instruction permettant de récupérer un élément au hasard dans une liste.
- Écrire une fonction permettant de piocher un élément au hasard dans une liste, de telle sorte que l’élément pioché n’y figure ensuite plus.
- Soit gamme = [‘Do’, ‘Ré’, ‘Mi’, ‘Fa’, ‘Sol’, ‘La’, ‘Si’]. Écrire une suite d’instructions qui génère à partir de gamme la liste de toutes les notes de la gamme sur 4 octaves, sous la forme [‘Do_1’, ‘Ré_1, …, ‘Si_4’].
- Supprimer en une seule opération la gamme 2.
Autres exercices sur les listes