3.2. Présentation des listes

Les listes sont le type de données à tout faire de Python. Si votre seule expérience des listes sont les tableaux de Visual Basic ou (à Dieu ne plaise) les datastores de Powerbuilder, accrochez-vous pour les listes Python.

NOTE
Une liste en Python est comme un tableau Perl. En Perl, les variables qui stockent des tableaux débutent toujours par le caractère @, en Python vous pouvez nommer votre variable comme bon vous semble et Python se chargera de la gestion du typage.
NOTE
Une liste Python est bien plus qu'un tableau en Java (même s'il peut être utilisé comme tel si vous n'attendez vraiment rien de mieux de la vie). Une meilleure analogie serait la classe ArrayList, qui peut contenir n'importe quels objets et qui croît dynamiquement au fur et à mesure que de nouveaux éléments y sont ajoutés.

3.2.1. Definition d'une liste

Exemple 3.6. Definition d'une liste

>>> li = ["a", "b", "mpilgrim", "z", "example"] 1
>>> li
['a', 'b', 'mpilgrim', 'z', 'example']
>>> li[0]                                       2
'a'
>>> li[4]                                       3
'example'
1 Premièrement, nous définissons une liste de 5 éléments. Notez qu'ils conservent leur ordre d'origine. Ce n'est pas un accident. Une liste est un ensemble ordonné d'éléments entouré par des crochets.
2 Une liste peut être utilisée comme un tableau dont l'indice de base est zéro. Le premier élément de toute liste non vide est toujours li[0].
3 Le dernier élément de cette liste de 5 éléments est li[4] car les listes sont toujours indicées à partir de zéro.

Exemple 3.7. Indices de liste négatifs

>>> li
['a', 'b', 'mpilgrim', 'z', 'example']
>>> li[-1] 1
'example'
>>> li[-3] 2
'mpilgrim'
1 Un indice négatif permet d'accéder aux éléments à partir de la fin de la liste en comptant à rebours. Le dernier élément de toute liste non vide est toujours li[-1].
2 Si vous trouvez que les indices négatifs prêtent à confusion, voyez-les comme suit : li[n] == li[n - len(li)]. Donc dans cette liste, li[-3] == li[5 - 3] == li[2].

Exemple 3.8. Découpage d'une liste

>>> li
['a', 'b', 'mpilgrim', 'z', 'example']
>>> li[1:3]  1
['b', 'mpilgrim']
>>> li[1:-1] 2
['b', 'mpilgrim', 'z']
>>> li[0:3]  3
['a', 'b', 'mpilgrim']
1 Vous pouvez obtenir un sous-ensemble d'une liste, appelé une «tranche» (slice), en spécifiant deux indices. La valeur de retour est une nouvelle liste contenant les éléments de la liste, dans l'ordre, en démarrant du premier indice de la tranche (dans ce cas li[1]), jusqu'à au second indice de la tranche non inclu (ici li[3]).
2 Le découpage fonctionne si un ou les deux indices sont négatifs. Pour vous aider, vous pouvez les voir commer ceci : en lisant la liste de gauche à droite, le premier indice spécifie le premier élément que vous désirez et le second indice spécifie le premier élément dont vous ne voulez pas. La valeur de retour est tout ce qui se trouve entre les deux.
3 Les listes sont indicées à partir de zéro, donc li[0:3] retourne les trois premiers éléments de la liste, en démarrant à li[0] jusqu'à li[3] non inclu.

Exemple 3.9. Raccourci pour le découpage

>>> li
['a', 'b', 'mpilgrim', 'z', 'example']
>>> li[:3] 1
['a', 'b', 'mpilgrim']
>>> li[3:] 2 3
['z', 'example']
>>> li[:]  4
['a', 'b', 'mpilgrim', 'z', 'example']
1 Si l'indice de tranche de gauche est 0, vous pouvez l'omettre et 0 sera implicite. Donc li[:3] est la même chose que li[0:3] dans le premier exemple.
2 De la même manière, si l'indice de tranche de droite est la longueur de la liste, vous pouvez l'omettre. Donc li[3:] est pareil que li[3:5], puisque la liste a 5 éléments.
3 Remarquez la symétrie. Dans cette liste de 5 éléments, li[:3] retourne les 3 premiers éléments et li[3:] retourne les deux derniers. En fait li[:n] retournera toujours les n premiers éléments et li[n:] le reste, quelle que soit la longueur de la liste.
4 Si les deux indices sont omis, tous les éléments de la liste sont inclus dans la tranche. Mais ce n'est pas la même chose que la liste li; c'est une nouvelle liste qui contient les même éléments. li[:] est un raccourci permettant d'effectuer une copie complète de la liste.

3.2.2. Ajout d'éléments à une liste

Exemple 3.10. Ajout d'éléments à une liste

>>> li
['a', 'b', 'mpilgrim', 'z', 'example']
>>> li.append("new")               1
>>> li
['a', 'b', 'mpilgrim', 'z', 'example', 'new']
>>> li.insert(2, "new")            2
>>> li
['a', 'b', 'new', 'mpilgrim', 'z', 'example', 'new']
>>> li.extend(["two", "elements"]) 3
>>> li
['a', 'b', 'new', 'mpilgrim', 'z', 'example', 'new', 'two', 'elements']
1 append ajoute un élément à la fin de la liste.
2 insert insère un élément dans la liste. L'argument numérique est l'indice du premier élément qui sera décalé. Notez que les éléments de la liste ne sont pas obligatoirement uniques ; il y a maintenant 2 éléments distincts avec la valeur 'new', li[2] and li[6].
3 extend concatène des listes. Notez que vous n'appelez pas extend avec plusieurs arguments mais bien avec un seul argument qui est une liste. Dans le cas présent, la liste est composée de deux éléments.

Exemple 3.11. Différence entre extend et append

>>> li = ['a', 'b', 'c']
>>> li.extend(['d', 'e', 'f']) 1
>>> li
['a', 'b', 'c', 'd', 'e', 'f']
>>> len(li)                    2
6
>>> li[-1]
'f'
>>> li = ['a', 'b', 'c']
>>> li.append(['d', 'e', 'f']) 3
>>> li
['a', 'b', 'c', ['d', 'e', 'f']]
>>> len(li)                    4
4
>>> li[-1]
['d', 'e', 'f']
1 Les listes ont deux méthodes, extend et append, qui semblent faire la même chose, mais sont en fait complètement différentes. extend prend un seul argument, qui est toujours une liste et ajoute chacun des éléments de cette liste à la liste originelle.
2 Ici nous avons une liste de trois éléments ('a', 'b' et 'c') et nous utilisons extended pour lui ajouter une liste de trois autres éléments ('d', 'e' et 'f'), ce qui nous donne une liste de six éléments.
3 Par contre, append prend un argument, qui peut être de n'importe quel type et l'ajoute simplement à la fin de la liste. Ici, nous appelons append avec un argument, qui est une liste de trois éléments.
4 Maintenant, la liste originelle qui avait trois éléments en contient quatre. Pourquoi quatre ? Parce que le dernier élément que nous venons d'ajouter est lui-même une liste. Les listes peuvent contenir n'importe quel type de données, y compris d'autres listes. En fonction du but recherché, faites attention de ne pas utiliser append si vous pensez en fait à extend.

3.2.3. Recherche dans une liste

Exemple 3.12. Recherche dans une liste

>>> li
['a', 'b', 'new', 'mpilgrim', 'z', 'example', 'new', 'two', 'elements']
>>> li.index("example") 1
5
>>> li.index("new")     2
2
>>> li.index("c")       3
Traceback (innermost last):
  File "<interactive input>", line 1, in ?
ValueError: list.index(x): x not in list
>>> "c" in li           4
False
1 index trouve la première occurrence d'une valeur dans la liste et retourne son indice.
2 index trouve la première occurrence d'une valeur dans la liste. Dans ce cas, new apparaît à deux reprises dans la liste, li[2] et li[6], mais index ne retourne que le premier indice, 2.
3 Si la valeur est introuvable dans la liste, Python déclenche une exception. C'est sensiblement différent de la plupart des autres langages qui retournent un indice invalide. Si cela peut sembler gênant, c'est en fait une bonne chose car cela signifie que votre programme se plantera à la source même du problème plutôt qu'au moment ou vous tenterez de manipuler l'indice non valide.
4 Pour tester la présence d'une valeur dans la liste, utilisez in, qui retourne True si la valeur a été trouvée et False dans le cas contraire.
NOTE
Avant la version 2.2.1, Python n'avait pas de type booléen. Pour compenser cela, Python acceptait pratiquement n'importe quoi dans un contexte requérant un booléen (comme une instruction if), en fonction des règles suivantes :
  • 0 est faux, tous les autres nombres sont vrai.
  • Une chaîne vide ("") est faux, toutes les autres chaînes sont vrai.
  • Une liste vide ([]) est faux, toutes les autres listes sont vrai.
  • Un tuple vide (()) est faux, tous les autres tuples sont vrai.
  • Un dictionnaire vide ({}) est faux, tous les autres dictionnaires sont vrai.
Ces règles sont toujours valides en Python 2.3.3 et au-delà, mais vous pouvez maintenant utiliser un véritable booléen, qui a pour valeur True ou False. Notez la majuscule, ces valeurs comme tout le reste en Python, sont sensibles à la casse.

3.2.4. Suppression d'éléments d'une liste

Exemple 3.13. Enlever des éléments d'une liste

>>> li
['a', 'b', 'new', 'mpilgrim', 'z', 'example', 'new', 'two', 'elements']
>>> li.remove("z")   1
>>> li
['a', 'b', 'new', 'mpilgrim', 'example', 'new', 'two', 'elements']
>>> li.remove("new") 2
>>> li
['a', 'b', 'mpilgrim', 'example', 'new', 'two', 'elements']
>>> li.remove("c")   3
Traceback (innermost last):
  File "<interactive input>", line 1, in ?
ValueError: list.remove(x): x not in list
>>> li.pop()         4
'elements'
>>> li
['a', 'b', 'mpilgrim', 'example', 'new', 'two']
1 remove enlève la première occurrence de la valeur de la liste.
2 remove enlève uniquement la première occurence de la valeur. Dans ce cas, new apparaît à deux reprises dans la liste mais li.remove("new") a seulement retiré la première occurrence.
3 Si la valeur est introuvable dans la liste, Python déclenche une exception. Ce comportement est identique à celui de la méthode index.
4 pop est un spécimen intéressant. Il fait deux choses : il enlève le dernier élément de la liste et il retourne la valeur qui a été enlevé. Notez que cela diffère de li[-1] qui retourne une valeur mais ne modifie pas la liste et de li.remove(valeur) qui altère la liste mais ne retourne pas de valeur.

3.2.5. Utilisation des opérateurs de listes

Exemple 3.14. Opérateurs de listes

>>> li = ['a', 'b', 'mpilgrim']
>>> li = li + ['example', 'new'] 1
>>> li
['a', 'b', 'mpilgrim', 'example', 'new']
>>> li += ['two']                2
>>> li
['a', 'b', 'mpilgrim', 'example', 'new', 'two']
>>> li = [1, 2] * 3              3
>>> li
[1, 2, 1, 2, 1, 2]
1 Les listes peuvent être concaténées à l'aide de l'opérateur +. liste = liste + autreliste est équivalent à list.extend(autreliste). Mais l'opérateur + retourne une nouvelle liste concaténée comme une valeur alors que extend modifie une liste existante. Cela implique que extend est plus rapide, surtout pour de grandes listes.
2 Python supporte l'opérateur +=. li += ['two'] est équivalent à li = li + ['two']. L'opérateur += fonctionne pour les listes, les chaînes et les entiers. Il peut être surchargé pour fonctionner également avec des classes définies par l'utilisateur (nous en apprendrons plus sur les classes au Chapitre 5).
3 L'opérateur * agit sur les liste comme un répéteur. li = [1, 2] * 3 est équivalent à li = [1, 2] + [1, 2] + [1, 2], qui concatène les trois listes en une seule.