Les listes


Qu'est ce qu'une liste ?

Conceptuellement et indépendamment d'un langage de programmation:

Une liste est une suite finie de données.

Une même donnée peut se répéter plusieurs fois dans la suite, c'est à dire à plusieurs positions.

Un mot par exemple, est une suite de lettres et donc, conceptuellement, c'est une liste. Dans un même mot, une même lettre peut se répéter plusieurs fois.

Un élément d'une liste est une donnée située à une position précise. Exemple: dans le mot thirion, le premier élément est t, le deuxième h, etc ... La donnée i, se répète deux fois:, en troisième et cinquième position. Nous dirons que le troisième et le cinquième élément ont la même valeur (i dans ce cas).

La longueur d'une liste est le nombre d'éléments qu'elle contient. Exemple: le mot thirion est une suite de longueur 7.

Les listes en Python

En Python:

Créer une liste

Une première manière de créer une liste en Python (nous en verrons d'autres par la suite), est de donner explicitement ses éléments entre crochets.

Commencons par la liste vide (liste ne contenant aucun élément) avec l'exemple suivant:

 L0 = []

Cette affectation crée une variable L0 dont la valeur est la liste vide.

Lorsque la liste n'est pas vide, ses éléments doivent être séparés par des virgules.

Exemple:

 L1 = [6, 6, 1961]

Cette affectation crée une variable L1 contenant une liste de trois éléments : les trois nombres 6, 6 et 1961.

Comme nous l'avons déjà précisé, les éléments d'une liste peuvent être de types quelconques et ne sont pas nécessairement tous de même type.

Par exemple, l'affectation:

 L2 = ["eric", "thirion", "né", "le" , 6 , "juin", 1961]

crée une variable L2 contenant une liste de longueur 7 dont certains éléments sont des chaines de caractères et d'autres, des nombres.

D'autre part, étant donné que les éléments d'une liste peuvent être de types quelconques et qu'une liste est un type de donnée, on en déduit que les éléments d'une liste peuvent être des listes !

Exemple:

 L3 = [["eric", "thirion"] , [6 ,"Juin", 1961 ]]

Cette affectation crée une variable L3 contenant une liste de deux éléments. Le premier élément de L3 est une liste de deux éléments: "eric" et "thirion". Le deuxième élément de L3 est une liste de trois éléments : 6, "juin" et 1961.

Enfin, dans les exemples vu jusqu'ici, les crochets contenaient soit des littéraux, soit des listes elles même constituées de littéraux. En fait, les crochets peuvent également contenir des expressions à calculer. Dans ce cas, les valeurs de ces expressions seront calculées avant que la liste soit effectivement construite à partir de ces valeurs.

Exemple:

A = 2
B = 5
L4 = [A, B, A+B, A*B]

Ici, L4 contiendra au final la liste [2 , 5, 7, 10].

Modifier une liste

Dans ce paragraphe, nous allons voir différentes opérations permettant de modifier une liste: modifier ou supprimer un élément, ajouter un élément .... etc

Mais avant cela, il faut savoir que chaque élément d'une liste est indicé. L'indice d'un élément définit sa position. L'indice du premier élément est zéro (et non pas un!), celui du deuxième : un, etc ... jusqu'au dernier dont l'indice est la longueur de la liste moins un.

Dans les explications qui suivent, L désignera une liste de longueur N et donc indicée de 0 à N-1.


Modification de la valeur d'un élément

La modification de la valeur de l'élément d'indice i se fait par une affectation du type:

  L[i] = expression

S'il n'existe pas d'élément d'indice i (liste vide ou i < 0 ou i >= N) , cette instruction provoquera une erreur.

Par exemple:

  L=[20,8,9,18,9,15,14]
  L[2] = 4

affecte la valeur 4 à l'élément d'indice 2 (le troisième élément). Après l'affectation, L vaudra donc [20,8,4,18,9,15,14].

Par contre:

  L=[20,8,9,18,9,15,14]
  L[7] = 4

provoquera une erreur d'exécution car il n'existe pas d'élément d'indice 7.


Supprimer un élément

La suppression de l'élément d'indice i se fait par :

 del  L[i] 

S'il n'existe pas d'élément d'indice i, cette instruction provoquera une erreur.

Par exemple:

  L=[20,8,9,18,9,15,14]
  del L[2] 

supprime l'élément d'indice 2. Après l'affectation, L vaudra [20,8,18,9,15,14].


Ajouter un élément

L'instruction suivante permet d'insérer un nouvel élément en position i:

L.insert(i, expression)

Si i est supérieur ou égal à la longueur de la liste, le nouvel élément sera ajouté en dernier.

Nous somme ici en présence d'une notation relevant de la programmation objet (l'utilisation du .) que nous aborderons ultérieurement. Pour l'instant, je vous demanderais de considérer que cette instruction est équivalente à l'appel de procédure suivant:

insert(L , i, expression)

D'autres instructions du même type interviendrons dans la suite du cours et devrons être interprétées provisoirement de cette manière.

Exemple d'insertion:

  L=[20,8,9,18,9,15,14]
  L.insert(4,7)

ici, un 7 sera inséré en 5ème position (indice 4) et la nouvelle liste sera [20,8,9,18,7,9,15,14].


Ajouter à la fin (ou empiler)

Pour ajouter un élément à la fin de la liste (cette opération s'appelle également empiler):

L.append(expression)

Exemple:

  L=[20,8,9,18,9,15,14]
  L.append(7)

ajoute un 7 à la fin de la liste. La nouvelle liste sera donc [20,8,9,18,9,15,14,7].

Notez que si l'on part d'une liste vide, on obtiendra une liste à un élément:

  L=[]
  L.append(7)

donne la liste [7].


Supprimer le dernier (ou dépiler)

Pour supprimer le dernier élément de la liste (cette opération s'appelle également dépiler):

  L.pop()

Si la liste est vide, cette opération provoquera une erreur. On peut également récupérer la valeur V du dernier élément en faisant:

  V = L.pop()

Exemple:

  L = [20,8,9,18,9,15,14]
  V = L.pop()

Après cette opération, V contiendra la valeur 14 et le contenu de la liste sera [20,8,9,18,9,15].

Concatener des listes

Tout comme les chaines de caractères (qui sont d'ailleurs conceptuellement des listes de caractères), les listes peuvent être concaténées. Il suffit pour cela d'utiliser l'opérateur +.

Exemple: la valeur de l'expression

  [20,8,9] + [18,9,15,14]

est la liste [20,8,9,18,9,15,14].

Python donne également la possibilité de multiplier une liste L par un nombre entier N, cela donne la même liste répétée N fois. Cette opération se donne L * N.

Exemple: la valeur de l'expression

  [1,2]*4

est la liste [1,2,1,2,1,2,1,2]

Les sous-listes

Une sous-liste d'une liste L est une partie de L constituée d'éléments consécutifs, ou autrement dit, constituée d'éléments de L dont les indices sont compris entre un indice minimal et un indice maximal.

En Python, il existe une notation spéciale pour désigner une sous-liste d'une liste L. Il s'agit de la notation:

 L[Imin:Imax]

Cette notation représente la sous-liste de L constituée de tous les éléments compris entre celui d'indice Imin (inclu) et celui d'indice Imax (exclu).


Extraire une sous-liste

Une première application de la notation L[Imin:Imax], est l'extraction d'une sous-liste.

Exemple:

  L = [20,8,9,18,9,15,14]
  L2 = L[3:6]

Dans cet exemple, L2 vaudra [18,9,15].

D'autre part, si Imin est ommis, l'interpréteur Python comprendra : à partir du début de la liste.

  L = [20,8,9,18,9,15,14]
  L2 = L[:5]

Dans cet exemple, L2 vaudra [20,8,9,18,9].

De même, si Imax est ommis, l'interpréteur Python comprendra : jusqu'à la fin de la liste.

  L = [20,8,9,18,9,15,14]
  L2 = L[3:]

Dans cet exemple, L2 vaudra [18,9,15,14].


Modifier une sous-liste

Une deuxième application est la modification d'une sous liste. Dans ce cas la notation L[Imin:Imax] apparaitra à gauche du signe =.

Exemple :

  L = [20,8,9,18,9,15,14]
  L[3:6] = [2,3,4,5]

Après ces deux instructions L contiendra [20,8,9,2,3,4,5,14].

On peut même supprimer tous les éléments d'une sous-liste en lui affectant la liste vide.

Exemple :

  L = [20,8,9,18,9,15,14]
  L[3:] = []

Après ces deux instructions L contiendra [20,8,9].

Présence d'une valeur

L'opérateur in

L'opérateur in permet de tester si une valeur est présente (au moins une fois) dans une liste. Plus précisement, l'expression

   V in L

est une expression logique dont la valeur est True si la valeur V est un élément de L et False sinon.

Exemple: avec L = [20,8,9,18,9,15,14] , 8 in L vaut True, 9 in L vaut True et 7 in L vaut False.


La fonction index

La fonction index permet de retrouver l'indice du premier élément d'une liste égal à une valeur donnée. Plus précisement, l'expression

    L.index(V)

a pour valeur l'indice du premier élément de L égal à V.

Attention: l'évaluation de cette expression provoquera une erreur si V n'est pas dans la liste.

Exemple: avec L = [20,8,9,18,9,15,14] , L.index(9) vaut 2.


La fonction count

La fonction count donne le nombre d'occurence d'une valeur dans une liste, c'est à dire le nombre de fois qu'elle se répète:

    L.count(V)

donne le nombre d'occurence de V dans L (en particulier 0 si V n'est pas dans L).

Exemple: avec L = [20,8,9,18,9,15,14] , L.count(15) vaut 1, L.count(7) vaut 0 et L.count(9) vaut 2.

Parcourir une liste

Dans de nombreux cas, les fonctions intégrées de python associées aux listes (insert, append, pop, count, ....) ne suffisent pas à résoudre le problème posé. Il faut alors savoir parcourir une liste à l'aide d'une boucle afin de traiter chaque élément.


Méthode 1: boucle for classique et fonction len

Une première solution pour parcourir une liste est d'utiliser une boucle for classique:

 for i in range (0,len(L)) :
      traiter l'élément L[i]

La fonction len retourne la longueur de la liste. Le compteur i prendra donc ici les valeurs 0,1, .... jusqu'à l'indice du dernier élément. Par conséquent L[i] contiendra successivement chaque élément de la liste.

Exemple:

Considérons le problème suivant: à partir d'une liste L1 de nombre entiers, on voudrait construire une liste L2 contenant les mêmes nombres élevés au carré. Avec L1=[4,5,3] on obtiendrait par exemple L2 = [16,25,9].

Avec la méthode que nous venons de décrire, cela donnerait:

L2 = []
for i in range (0,len(L1)) :
      L2.append(L1[i]*L1[i])

Méthode 2: boucle for sans range

Une deuxième méthode est l'utilisation d'une nouvelle structure de contrôle. Il s'agit d'une variante de la boucle for spécialement adaptée au parcours d'une liste. Cette variante s'écrit sans range de la manière suivante:

 for e in L:
      traiter l'élément e

Avec cette écriture plus simple que la précédente, la variable e prendra successivement la valeur de chaque élément de la liste. Le seul inconvénient de cette deuxième méthode par rapport à la première est que l'on ne récupère pas l'indice de l'élément dans le traitement. Il vaudra donc mieux utiliser la première méthode si le traitement d'un élément dépend également de sa position.

Exemple:

Avec le même problème que précédemment, on obtient:

L2 = []
for e in  L1 :
      L2.append(e * e)

Exemple où la méthode 1 est préférable

Supposons que l'on veuille extraire les éléments d'indice impair d'une liste L1 pour en faire une liste L2. L1 = [20,8,9,18,9,15,14] donnerait par exemple L2 = [8,18,15]. Ici, la simple connaissance de la valeur d'un élément de L1 ne suffit pas à résoudre le problème, puisque tout dépend de la position de cet élément dans la liste. On ne pourra donc pas utiliser la méthode 2 pour résoudre le problème, mais la méthode 1 conviendra:

L2=[]
for i in range(0,len(L)) :
    if i % 2 == 1 :
        L2.append(L[i])

Rappel: l'opérateur % retourne le reste de la division par un nombre entier.

Comparer deux listes

Deux listes sont identiques si elles ont la même longueur et que les élément de même indice sont égaux. Remarquez que tester l'égalité de deux listes n'est pas forcément un problème évident puisque les éléments des deux listes peuvent être eux même des listes !

Heureusement Python, nous évite de résoudre ce problème par programmation en nous permettant de comparer deux listes avec l'opérateur ==.

Exemples

L1 L2 L1 == L2
[1,9,6,1] [1,9,6,1] True
[1,9,6,1] [9,6,1,1] False
[1,9,6] [1,9,6,1] False
[1,9,6,[1,9,3,5],1] [1,9,6,[1,9,3,5],1] True
[1,9,6,[1,9,3,5],1] [1,9,6,[1,9,6,1],1] False