Apprenez à programmer en Python
Last updated on Monday, September 8, 2014
  • 4 semaines
  • Facile

Ce cours est visible gratuitement en ligne.

Paperback available in this course

Ce cours existe en eBook.

Certificate of achievement available at the end this course

Got it!

Les listes et tuples (1/2)

J'aurai réussi à vous faire connaître et, j'espère, aimer le langage Python sans vous apprendre les listes. Mais allons ! Cette époque est révolue. Maintenant que nous commençons à étudier l'objet sous toutes ses formes, je ne vais pas pouvoir garder le secret plus longtemps : il existe des listes en Python. Pour ceux qui ne voient même pas de quoi je parle, vous allez vite vous rendre compte qu'avec les dictionnaires (que nous verrons plus loin), c'est un type, ou plutôt une classe, dont on aura du mal à se passer.

Les listes sont des séquences. En fait, leur nom est plutôt explicite, puisque ce sont des objets capables de contenir d'autres objets de n'importe quel type. On peut avoir une liste contenant plusieurs nombres entiers (1, 2, 50, 2000 ou plus, peu importe), une liste contenant des flottants, une liste contenant des chaînes de caractères... et une liste mélangeant ces objets de différents types.

Créons et éditons nos premières listes

D'abord c'est quoi, une liste ?

En Python, les listes sont des objets qui peuvent en contenir d'autres. Ce sont donc des séquences, comme les chaînes de caractères, mais au lieu de contenir des caractères, elles peuvent contenir n'importe quel objet. Comme d'habitude, on va s'occuper du concept des listes avant de voir tout son intérêt.

Création de listes

On a deux moyens de créer des listes. Si je vous dis que la classe d'une liste s'appelle, assez logiquement, list, vous devriez déjà voir une manière de créer une liste.

Non ? …

Vous allez vous habituer à cette syntaxe :

>>> ma_liste = list() # On crée une liste vide
>>> type(ma_liste)
<class 'list'>
>>> ma_liste
[]
>>>

Là encore, on utilise le nom de la classe comme une fonction pour instancier un objet de cette classe.

Quand vous affichez la liste, vous pouvez constater qu'elle est vide. Entre les crochets (qui sont les délimiteurs des listes en Python), il n'y a rien. On peut également utiliser ces crochets pour créer une liste.

>>> ma_liste = [] # On crée une liste vide
>>>

Cela revient au même, vous pouvez vérifier. Toutefois, on peut également créer une liste non vide, en lui indiquant directement à la création les objets qu'elle doit contenir.

>>> ma_liste = [1, 2, 3, 4, 5] # Une liste avec cinq objets
>>> print(ma_liste)
[1, 2, 3, 4, 5]
>>>

La liste que nous venons de créer compte cinq objets de type int. Ils sont classés par ordre croissant. Mais rien de tout cela n'est obligatoire.

  • Vous pouvez faire des listes de toute longueur.

  • Les listes peuvent contenir n'importe quel type d'objet.

  • Les objets dans une liste peuvent être mis dans un ordre quelconque. Toutefois, la structure d'une liste fait que chaque objet a sa place et que l'ordre compte.

>>> ma_liste = [1, 3.5, "une chaine", []]
>>>

Nous avons créé ici une liste contenant quatre objets de types différents : un entier, un flottant, une chaîne de caractères et… une autre liste.

Voyons à présent comment accéder aux éléments d'une liste :

>>> ma_liste = ['c', 'f', 'm']
>>> ma_liste[0] # On accède au premier élément de la liste
'c'
>>> ma_liste[2] # Troisième élément
'm'
>>> ma_liste[1] = 'Z' # On remplace 'f' par 'Z'
>>> ma_liste
['c', 'Z', 'm']
>>>

Comme vous pouvez le voir, on accède aux éléments d'une liste de la même façon qu'on accède aux caractères d'une chaîne de caractères : on indique entre crochets l'indice de l'élément qui nous intéresse.

Contrairement à la classe str, la classe list vous permet de remplacer un élément par un autre. Les listes sont en effet des types dits mutables.

Insérer des objets dans une liste

On dispose de plusieurs méthodes, définies dans la classe list, pour ajouter des éléments dans une liste.

Ajouter un élément à la fin de la liste

On utilise la méthode append pour ajouter un élément à la fin d'une liste.

>>> ma_liste = [1, 2, 3]
>>> ma_liste.append(56) # On ajoute 56 à la fin de la liste
>>> ma_liste
[1, 2, 3, 56]
>>>

C'est assez simple non ? On passe en paramètre de la méthode append l'objet que l'on souhaite ajouter à la fin de la liste.

Ceci est extrêmement important. Dans le chapitre précédent, nous avons vu qu'aucune des méthodes de chaînes ne modifie l'objet d'origine mais qu'elles renvoient toutes un nouvel objet, qui est la chaîne modifiée. Ici c'est le contraire : les méthodes de listes ne renvoient rien mais modifient l'objet d'origine. Regardez ce code si ce n'est pas bien clair :

>>> chaine1 = "une petite phrase"
>>> chaine2 = chaine1.upper() # On met en majuscules chaine1
>>> chaine1                   # On affiche la chaîne d'origine
'une petite phrase'
>>> # Elle n'a pas été modifiée par la méthode upper
... chaine2                   # On affiche chaine2
'UNE PETITE PHRASE'
>>> # C'est chaine2 qui contient la chaîne en majuscules
... # Voyons pour les listes à présent
... liste1 = [1, 5.5, 18]
>>> liste2 = liste1.append(-15) # On ajoute -15 à liste1
>>> liste1                      # On affiche liste1
[1, 5.5, 18, -15]
>>> # Cette fois, l'appel de la méthode a modifié l'objet d'origine (liste1)
... # Voyons ce que contient liste2
... liste2
>>> # Rien ? Vérifions avec print
... print(liste2)
None
>>>

Je vais expliquer les dernières lignes. Mais d'abord, il faut que vous fassiez bien la différence entre les méthodes de chaînes, où l'objet d'origine n'est jamais modifié et qui renvoient un nouvel objet, et les méthodes de listes, qui ne renvoient rien mais modifient l'objet d'origine.

J'ai dit que les méthodes de listes ne renvoient rien. On va pourtant essayer de « capturer » la valeur de retour dans liste2. Quand on essaye d'afficher la valeur de liste2 par saisie directe, on n'obtient rien. Il faut l'afficher avec print pour savoir ce qu'elle contient : None. C'est l'objet vide de Python. En réalité, quand une fonction ne renvoie rien, elle renvoie None. Vous retrouverez peut-être cette valeur de temps à autre, ne soyez donc pas surpris.

Insérer un élément dans la liste

Nous allons passer assez rapidement sur cette seconde méthode. On peut, très simplement, insérer un objet dans une liste, à l'endroit voulu. On utilise pour cela la méthode insert.

>>> ma_liste = ['a', 'b', 'd', 'e']
>>> ma_liste.insert(2, 'c') # On insère 'c' à l'indice 2
>>> print(ma_liste)
['a', 'b', 'c', 'd', 'e']

Quand on demande d'insérer c à l'indice 2, la méthode va décaler les objets d'indice supérieur ou égal à 2. c va donc s'intercaler entre b et d.

Concaténation de listes

On peut également agrandir des listes en les concaténant avec d'autres.

>>> ma_liste1 = [3, 4, 5]
>>> ma_liste2 = [8, 9, 10]
>>> ma_liste1.extend(ma_liste2) # On insère ma_liste2 à la fin de ma_liste1
>>> print(ma_liste1)
[3, 4, 5, 8, 9, 10]
>>> ma_liste1 = [3, 4, 5]
>>> ma_liste1 + ma_liste2
[3, 4, 5, 8, 9, 10]
>>> ma_liste1 += ma_liste2 # Identique à extend
>>> print(ma_liste1)
[3, 4, 5, 8, 9, 10]
>>>

Voici les différentes façons de concaténer des listes. Vous pouvez remarquer l'opérateur + qui concatène deux listes entre elles et renvoie le résultat. On peut utiliser += assez logiquement pour étendre une liste. Cette façon de faire revient au même qu'utiliser la méthode extend.

Suppression d'éléments d'une liste

Nous allons voir rapidement comment supprimer des éléments d'une liste, avant d'apprendre à les parcourir. Vous allez vite pouvoir constater que cela se fait assez simplement. Nous allons voir deux méthodes pour supprimer des éléments d'une liste :

  • le mot-clé del ;

  • la méthode remove.

Le mot-clé del

C'est un des mots-clés de Python, que j'aurais pu vous montrer plus tôt. Mais les applications de del me semblaient assez peu pratiques avant d'aborder les listes.

del (abréviation de delete) signifie « supprimer » en anglais. Son utilisation est des plus simple : del variable_a_supprimer. Voyons un exemple.

>>> variable = 34
>>> variable
34
>>> del variable
>>> variable
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'variable' is not defined
>>>

Comme vous le voyez, après l'utilisation de del, la variable n'existe plus. Python l'efface tout simplement. Mais on peut également utiliser del pour supprimer des éléments d'une séquence, comme une liste, et c'est ce qui nous intéresse ici.

>>> ma_liste = [-5, -2, 1, 4, 7, 10]
>>> del ma_liste[0] # On supprime le premier élément de la liste
>>> ma_liste
[-2, 1, 4, 7, 10]
>>> del ma_liste[2] # On supprime le troisième élément de la liste
>>> ma_liste
[-2, 1, 7, 10]
>>>
La méthode remove

On peut aussi supprimer des éléments de la liste grâce à la méthode remove qui prend en paramètre non pas l'indice de l'élément à supprimer, mais l'élément lui-même.

>>> ma_liste = [31, 32, 33, 34, 35]
>>> ma_liste.remove(32)
>>> ma_liste
[31, 33, 34, 35]
>>>

La méthode remove parcourt la liste et en retire l'élément que vous lui passez en paramètre. C'est une façon de faire un peu différente et vous appliquerez del ou remove en fonction de la situation.

Notez au passage que le mot-clé del n'est pas une méthode de liste. Il s'agit d'une fonctionnalité de Python qu'on retrouve dans la plupart des objets conteneurs, tels que les listes que nous venons de voir, ou les dictionnaires que nous verrons plus tard. D'ailleurs, del sert plus généralement à supprimer non seulement des éléments d'une séquence mais aussi, comme nous l'avons vu, des variables.

Nous allons à présent voir comment parcourir une liste, même si vous devez déjà avoir votre petite idée sur la question.

Le parcours de listes

Vous avez déjà dû vous faire une idée des méthodes pour parcourir une liste. Je vais passer brièvement dessus, vous ne verrez rien de nouveau ni, je l'espère, de très surprenant.

>>> ma_liste = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h']
>>> i = 0 # Notre indice pour la boucle while
>>> while i < len(ma_liste):
...     print(ma_liste[i])
...     i += 1 # On incrémente i, ne pas oublier !
... 
a
b
c
d
e
f
g
h
>>> # Cette méthode est cependant préférable
... for elt in ma_liste: # elt va prendre les valeurs successives des éléments de ma_liste
...     print(elt)
... 
a
b
c
d
e
f
g
h
>>>

Il s'agit des mêmes méthodes de parcours que nous avons vues pour les chaînes de caractères, au chapitre précédent. Nous allons cependant aller un peu plus loin.

La fonction enumerate

Les deux méthodes que nous venons de voir possèdent toutes deux des inconvénients :

  • la méthode utilisant while est plus longue à écrire, moins intuitive et elle est perméable aux boucles infinies, si l'on oublie d'incrémenter la variable servant de compteur ;

  • la méthode par for se contente de parcourir la liste en capturant les éléments dans une variable, sans qu'on puisse savoir où ils sont dans la liste.

C'est vrai dans le cas que nous venons de voir. Certains codeurs vont combiner les deux méthodes pour plus de flexibilité mais, très souvent, le code obtenu est moins lisible. Heureusement, les développeurs de Python ont pensé à nous.

>>> ma_liste = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h']
>>> for i, elt in enumerate(ma_liste):
...     print("À l'indice {} se trouve {}.".format(i, elt))
... 
À l'indice 0 se trouve a.
À l'indice 1 se trouve b.
À l'indice 2 se trouve c.
À l'indice 3 se trouve d.
À l'indice 4 se trouve e.
À l'indice 5 se trouve f.
À l'indice 6 se trouve g.
À l'indice 7 se trouve h.
>>>

Pas de panique !

Nous avons ici une boucle for un peu surprenante. Entre for et in, nous avons deux variables, séparées par une virgule.

En fait, enumerate prend en paramètre une liste et renvoie un objet qui peut être associé à une liste contenant deux valeurs par élément : l'indice et l'élément de la liste parcouru.

Ce n'est sans doute pas encore très clair. Essayons d'afficher cela un peu mieux :

>>> for elt in enumerate(ma_liste):
...     print(elt)
... 
(0, 'a')
(1, 'b')
(2, 'c')
(3, 'd')
(4, 'e')
(5, 'f')
(6, 'g')
(7, 'h')
>>>

Quand on parcourt chaque élément de l'objet renvoyé par enumerate, on voit des tuples qui contiennent deux éléments : d'abord l'indice, puis l'objet se trouvant à cet indice dans la liste passée en argument à la fonction enumerate.

Si les parenthèses vous déconcertent trop, vous pouvez imaginer, à la place, des crochets : dans cet exemple, cela revient au même.

Quand on utilise enumerate, on capture l'indice et l'élément dans deux variables distinctes. Voyons un autre exemple pour comprendre ce mécanisme :

>>> autre_liste = [
...     [1, 'a'],
...     [4, 'd'],
...     [7, 'g'],
...     [26, 'z'],
... ] # J'ai étalé la liste sur plusieurs lignes
>>> for nb, lettre in autre_liste:
...     print("La lettre {} est la {}e de l'alphabet.".format(lettre, nb))
... 
La lettre a est la 1e de l'alphabet.
La lettre d est la 4e de l'alphabet.
La lettre g est la 7e de l'alphabet.
La lettre z est la 26e de l'alphabet.
>>>

J'espère que c'est assez clair dans votre esprit. Dans le cas contraire, décomposez ces exemples, le déclic devrait se faire.

Par exemple, on peut être confronté à des exceptions IndexError si on tente de supprimer certains éléments d'une liste en la parcourant.

Nous verrons au prochain chapitre comment faire cela proprement, pour l'heure il vous suffit de vous méfier d'un parcours qui modifie une liste, surtout sa structure. D'une façon générale, évitez de parcourir une liste dont la taille évolue en même temps.

Allez ! On va jeter un coup d'œil aux tuples, pour conclure ce chapitre !

Un petit coup d'œil aux tuples

Nous avons brièvement vu les tuples un peu plus haut, grâce à la fonction enumerate. Les tuples sont des listes immuables, qu'on ne peut modifier. En fait, vous allez vous rendre compte que nous utilisons depuis longtemps des tuples sans nous en rendre compte.

Un tuple se définit comme une liste, sauf qu'on utilise comme délimiteur des parenthèses au lieu des crochets.

tuple_vide = ()
tuple_non_vide = (1,)
tuple_non_vide = (1, 3, 5)

À la différence des listes, les tuples, une fois créés, ne peuvent être modifiés : on ne peut plus y ajouter d'objet ou en retirer.

Une petite subtilité ici : si on veut créer un tuple contenant un unique élément, on doit quand même mettre une virgule après celui-ci. Sinon, Python va automatiquement supprimer les parenthèses et on se retrouvera avec une variable lambda et non un tuple contenant cette variable.

Mais à quoi cela sert-il ?

Il est assez rare que l'on travaille directement sur des tuples. C'est, après tout, un type que l'on ne peut pas modifier. On ne peut supprimer d'éléments d'un tuple, ni en ajouter. Cela vous paraît peut-être encore assez abstrait mais il peut être utile de travailler sur des données sans pouvoir les modifier.

En attendant, voyons plutôt les cas où nous avons utilisé des tuples sans le savoir.

Affectation multiple

Tous les cas que nous allons voir sont des cas d'affectation multiple. Vous vous souvenez ?

>>> a, b = 3, 4
>>> a
3
>>> b
4
>>>

On a également utilisé cette syntaxe pour permuter deux variables. Eh bien, cette syntaxe passe par des tuples qui ne sont pas déclarés explicitement. Vous pourriez écrire :

>>> (a, b) = (3, 4)
>>>

Quand Python trouve plusieurs variables ou valeurs séparées par des virgules et sans délimiteur, il va les mettre dans des tuples. Dans le premier exemple, les parenthèses sont sous-entendues et Python comprend ce qu'il doit faire.

Une fonction renvoyant plusieurs valeurs

Nous ne l'avons pas vu jusqu'ici mais une fonction peut renvoyer deux valeurs ou même plus :

def decomposer(entier, divise_par):
    """Cette fonction retourne la partie entière et le reste de
    entier / divise_par"""

    p_e = entier // divise_par
    reste = entier % divise_par
    return p_e, reste

Et on peut ensuite capturer la partie entière et le reste dans deux variables, au retour de la fonction :

>>> partie_entiere, reste = decomposer(20, 3)
>>> partie_entiere
6
>>> reste
2
>>>

Là encore, on passe par des tuples sans que ce soit indiqué explicitement à Python. Si vous essayez de faire retour = decomposer(20, 3), vous allez capturer un tuple contenant deux éléments : la partie entière et le reste de 20 divisé par 3.

Nous verrons plus loin d'autres exemples de tuples et d'autres utilisations. Je pense que cela suffit pour cette fois.

En résumé

  • Une liste est une séquence mutable pouvant contenir plusieurs autres objets.

  • Une liste se construit ainsi : liste = [element1, element2, elementN].

  • On peut insérer des éléments dans une liste à l'aide des méthodes append, insert et extend.

  • On peut supprimer des éléments d'une liste grâce au mot-clé del ou à la méthode remove.

  • Un tuple est une séquence pouvant contenir des objets. À la différence de la liste, le tuple ne peut être modifié une fois créé.

Example of certificate of achievement
Example of certificate of achievement