Les listes sont des objets très importants en Python car elles permettent de stocker de multiples informations dans une seule variable.

Ci dessous, voici un exemple montrant la liste des entiers de 0 à 9.

list(range(10))

Nous allons dans ce chapitre détailler ce qu'est une liste, comment les manipuler et expliquer pourquoi elles sont si importantes en Informatique.

Manipulation de listes

Présentation du type list

Comme on peut le voir sur l'exemple précédent, une liste en Python est un objet délimité par deux crochets et qui renferme un nombre fini d'éléments de n'importe quel type, ces éléments étant séparés par des virgules.

Voici quelques caractéristiques sur les listes

  • les éléments d'une liste sont ordonnés :si on échange de place deux éléments différents d'une liste, la liste est modifiée.>- les éléments d'une liste sont numérotés depuis 0
  • un même objet peut appparaître plusieurs fois dans une liste.
  • une liste peut contenir des éléments de type différents (nombres, chaines...)
Premier_Exemple=[21,"Bonjour",1+2,[1,2,3,1], 21 ]
print(Premier_Exemple)
print(Premier_Exemple[0])

Premières manipulations sur les listes

Créez une variable liste_carres contenant la liste les carrés des entiers de 1 à 10

liste_carres = ...
assert 81 in liste_carres

Les éléments d'une liste sont numérotés à partir de 0. On accède à un élément en utilisant une notation crochet : maListe[index].

Observez l'exemple et modifiez le pour accéder aux différents éléments de la liste_carres

Observez le message d'erreur lorsque l'index dépasse le nombre d'éléments dans la liste !

liste_carres[0]
liste_carres[11]

Il est possible de modifier un élément particulier d'une liste. Il suffit de faire une affectation au moyen du signe = comme pour une simple variable. Observez plutôt :

liste_carres[1]=100
print(liste_carres)

On peut rechercher si un élément dans une liste. Par exemple pour savoir si 25 est un carré, on peut taper la ligne suivante.

Manipulez cette fonction en testant des nombres qui sont dans la liste et d'autres qui n'y sont pas.

On sera frappé par la similitude entre la syntaxe de python et le langage naturel. Cette simplicité est une des forces de Python.

25 in liste_carres

On peut mettre deux listes bout à bout comme on le voit sur l'exemple suivant. On remarque l'utilisation naturelle du signe '+' pour ajouter deux listes bout à bout.

liste_carres=liste_carres + [121,144,169,196,225]
print(liste_carres)

De même qu'on possède l'opération +, il existe aussi l'opération * pour obtenir une liste formée de plusieurs fois la même liste. Je vous laisse découvrir le fonctionnement de cet opérateur dans la cellule ci-dessous :

3*[1,2,4]

Pour savoir combien d'éléments contient une liste, on peut utiliser la fonction len().

Testez aussi les fonctions min() et max() sur la liste_carres. A quoi servent elles ?

len(liste_carres)
print(min(liste_carres))
print(max(liste_carres))

Pour connaître la position d'un objet dans une liste, on peut utiliser la méthode *.index(). Elle s'utilise comme suit. Que se passe t-il si l'objet recherché n'appartient pas à la liste ?

liste_carres.index(81)

De la même manière, on peut compter le nombre d'éléments dans une liste. Pour cela, on utilise la méthode .count() de manière similaire à .index(). Pour vous exercer, ajouter à liste_carres la liste [121,81,169,81] et comptez le nombre d'occurences du nombre 81.

# A vous de jouer dans cette cellule
liste_carres=...

Parcourir une liste

Il existe deux manières de parcourir une liste :

  • le parcours élément par élément
  • le parcours par index

Dans les deux cas on utilisera une boucle pour. Observez les exemples suivants :

# Parcours élément par élément
for elmt in liste_carres:
    print ("ce nombre est un carré : ",elmt)
    
# Parcours par index
longueur_liste = len(liste_carres)
for indx in range(longueur_liste):
    print ("ce nombre est aussi un carré : ",liste_carres[indx])

Dans le parcours par élément, la variable de boucle contient les différents éléments de la liste. Dans le second parcours par index, la variable de boucle est l'index permettant d'accéder à l'élément. Il faut dans ce cas commencer par déterminer la longueur de la liste pour ne pas risquer un dépassement d'index.

Exercice 1

  1. Ecrire une fonction etendue

    • prenant en paramètre une liste de nombres
    • renvoyant l'étendue de cette liste à savoir l'écart entre la plus grande valeur et la plus petite valeur
  2. Ecrire une fonction somme

    • prenant en argument une liste
    • renvoyant la somme de tous les termes de la liste
  3. Ecrire une fonction moyenne

    • prenant en paramètre une liste de nombres
    • renvoyant la valeur moyenne des nombres de la liste
# YOUR CODE HERE
raise NotImplementedError()

La cellule de tests suivante doit s'exécuter sans erreur

assert somme(list(range(1,30))) == 435
assert etendue([3,1,9,4,5])==8
assert moyenne([3,1,9,4,5])==4.4

Modification d'une liste

Pour modifier une liste, il suffit d'effectuer une affectation à l'un de ses éléments via son index. Observez les exemples ci-dessous. Que signifie l'index -1 dans une liste ?

L=[[1,2,3],"bonjour",3]
print("Liste initiale ",L)
L[0]=[6,8]
print("Premier élément modifié :",L)
L[-1]="au revoir"
print("Qu'est-ce qui a changé ?", L)
L[0][-1]=9
print("On modifie le premier élément :",L)

Les méthodes sur les listes

Il existe encore d'autres moyens de manipulation de listes.

Il existe en fait des fonctions intégrées à la structure de listes permettant d'agir sur celles-ci : on les nomme méthodes et leur syntaxe générale est, étant donnée une liste $L$ :

$L.Methode()$, où $Methode()$ fait référence à l'une des méthodes détaillée ci-dessous.

Il est à noter qu'une fois la ligne $L.Methode()$ executée, la liste $L$ est, en général, transformée en sa liste modifiée.

Ces méthodes revoient à la programmation orientée objet de Python : les listes sont des objets qui sont manipulés, modifiés selon certains transformations et évoluent au grés de ces modifications.

Voici un petit catalogue des méthodes utiles. Vous retrouverez des méthodes déjà vues ci-dessus.

La méthode .append()

La syntaxe $L.append(objet)$ ajoute $objet$ à droite dans $L$ :

L=[1,2,3,4]
L.append(5)
print(L)  # la liste initiale vient d'être modifiée !

La méthode .insert()

La syntaxe $L.insert(Indice,objet)$ insère $objet$ en place $Indice$ dans la liste $L$ et décale le reste des occurrences de $L$ à droite :

L=["Pomme","Poire","Banane"]
print(L)
L.insert(1,"Fraise") # vient prendre la place de "Poire"
print(L)
L.insert(-1,"Ananas") # vient prendre la place de "Banane"
print(L)

La méthode .remove()

La syntaxe $L.remove(objet)$ supprime de la liste la première occurrence égale à $objet$ dans la liste $L$. Si $objet$ n'est pas présent dans $L$, cela produit un message d'erreur.

M=[2,3,2,3,3,2,3]
print(M)
M.remove(2)
print(M)  # seul le premier "2" est supprimé !
M.remove(3)
print(M)  # seul le premier "3" est supprimé !

La méthode .pop()

La syntaxe $L.pop([Indice])$ renvoie $L[Indice]$ et supprime l'élément d'index $Indice$ de la liste $L$. Il n'est pas nécessaire que $Indice$ soit dans les bornes cycliques licites entre $-len(L)$ et $len(L)-1$, mais cela est quand même conseillé pour une meilleure lecture du script.

L=[2,3,2,2,1,2,"mot",2,3]
print(L)
print(L.pop(6))
print(L)
L.pop(-1)
print(L)
L.pop(3)
print(L)

La méthode .index()

La syntaxe $L.index(objet)$ renvoie l'index de la première occurrence d'$objet$ dans $L$. La liste $L$ n'est pas modifiée par cette méthode. Cela renvoie un message d'erreur lorsque $objet$ ne figure pas dans la liste $L$.

Liste=[2,1,2,"un mot",3,2,3,2]
print(Liste)
print(Liste.index("un mot"))
print(Liste.index(3))
print(Liste)  # liste non modifiée

La méthode .count()

La syntaxe $L.count(objet)$ renvoie le nombre d'occurrences égales à $objet$ dans la liste $L$. Cele ne modifie pas la liste initiale.

Liste.count(2)

Tranches de listes

Etant donnée une liste $L$, la syntaxe $L[Indice$$Debut:Indice$$Fin:Pas]$ renvoie la sous-liste composée des termes $L[k]$, où l'indice $k$ vaut successivement $Indice$$Debut$,$Indice$$Debut$+$Pas$, $Indice$$Debut$+2 $Pas$, etc. On s'arrête avant d'avoir atteint $Indice$$Fin$. Le dernier indice n''est jamais inclus dans la sélection.

Il est à noter que $Pas$ peut être strictement négatif. Regardez attentivement les exemples suivants. N'hésitez pas à les modifier pour observer l'influence de chaque indice.

L=list(range(30)) # list() trasnforme un objet en liste
print("affichage de toute la liste : ",L)
print("une liste du troisième au dixième terme :",L[2:10])
print("affichage de certains termes : ", L[3:28:6])
print("affichage sans le premier terme :", L[1:])
print("affichage des cinq premiers termes :",L[:5])
print("la liste dans le sens inverse :",L[::-1])

Exercice 2 : Simulation de lancer de dé

  1. Ecrire une fonction genere_liste
    • prenant en paramètre un entier $n$
    • renvoyant une liste de $n$ nombres aléatoires entre 1 et 6
  2. Ecrire une fonction frequence_6
    • prenant en paramètre une liste de nombres
    • renvoyant la fréquence d'apparition du 6

Indication : On pourra utiliser les commandes suivantes pour tirer un nombre aléatoire entre 1 et 6 :

from random import * # A mettre au début du programme

randint(1,6)
from random import * # A mettre au début du programme

# YOUR CODE HERE
raise NotImplementedError()