Section 4.7
Séquences
Dans cette section, nous allons voir comment manipuler en Python des types de données plus complexes que les nombres et les booléens. En particulier, nous allons voir comment manipuler des séquences de données, c'est-à-dire des types de données qui peuvent contenir une suite ordonnée de valeurs.
Nous allons voir trois types de séquences : les chaînes de caractères, les listes et les tuples. Ces trois types de données sont très similaires et partagent de nombreuses opérations.
Nous allons commencer par voir les chaînes de caractères, que vous avez déjà rencontrées dans les chapitres précédents.
Les chaînes de caractères
Comme nous l'avons vu précédemment dans ce chapitre,
les chaînes de caractères sont des séquences de caractères
qui servent à représenter du texte.
Nous avons déjà vu comment créer des chaînes de caractères
à l'aide de guillemets simples ou doubles.
De plus, nous avions vu comment concaténer des chaînes
à l'aide de l'opérateur +
.
Dans cette section, nous allons voir différentes manières de manipuler de telles chaînes de caractères.
Longueur
Comme nous l'avions vu précédemment, la fonction len
sert
à connaître la longueur d'une chaîne de caractères,
c'est-à-dire le nombre de caractères qu'elle contient.
Cette fonction sera la même pour les listes et les tuples que nous aborderons plus tard.
Accéder à un élément
Pour accéder à un caractère i
d'une chaîne chaine
,
on utilise la notation chaine[i]
.
On indique entre les crochets l'indice du caractère
auquel on veut accéder.
Attention, en Python les indices commencent à 0,
ce qui signifie que le premier caractère d'une chaîne
est à l'indice 0 et que le dernier caractère est à l'indice
len(chaine) - 1
.
Les éléments d'une chaîne de caractères sont les caractères individuels de la chaîne. En Python, ces éléments sont représentés par des chaînes de caractères de longueur 1. D'autres langages de programmations utiliserons parfois un type de données particulier pour les caractères individuel, ce qui n'est pas le cas en Python.
! Remarque
En Python, il est possible de mettre un indice négatif
entre les crochets. Dans ce cas, l'indice est compté à partir
de la fin de la chaîne. Ainsi, chaine[-1]
fait référence au dernier caractère de la chaîne,
chaine[-2]
au caractère avant-dernier, et
ainsi de suite.
Itérer sur les éléments
Il est possible d'utiliser la boucle for
pour itérer sur les caractères d'une chaîne de caractères,
et ce sans avoir à utiliser d'indice.
À noter qu'il est aussi tout à fait possible d'itérer sur les
caractères d'une chaîne en utilisant un indice,
que ce soit via une boucle for
ou une boucle while
comme dans le code suivant.
Extraire une sous-chaîne
En Python, il est possible d'extraire une sous-chaîne
d'une chaine de caractères chaine
à l'aide de la notation
chaine[debut:fin]
, où debut
et fin
sont respectivement l'indice de début (compris) et l'indice de fin (non-compris) de la sous-chaîne.
! Remarque
Il est possible d'omettre l'indice de début ou l'indice de fin
dans la notation chaine[debut:fin]
.
Dans ce cas, l'indice de début est considéré comme étant 0 s'il n'est pas précisé,
alors que l'indice de fin est considéré comme étant len(chaine)
.
Si on omet les deux indices, on obtient une copie de la chaîne entière.
À noter qu'il est aussi possible d'utiliser des indices négatif, avec le même comportement que pour l'accès à un élément.
Rechercher un caractère
Il est possible de rechercher un caractère dans une chaîne de caractères
à l'aide de la méthode find
.
Cette méthode renvoie l'indice du premier caractère de la chaîne
qui correspond au caractère recherché.
Si le caractère n'est pas trouvé, la méthode renvoie -1.
! Remarque
On appelle méthode une fonction qui est associée à un objet.
Dans le cas présent, la méthode find
est associée à l'objet
chaine
, qui est une chaîne de caractères.
Nous aurons l'occasion de revenir sur les objets et les méthodes
à l'avenir, mais pour l'instant, il suffit de savoir que
pour appeler une méthode, on utilise simplement la notation objet.methode()
.
Notez que la méthode find
est exclusive aux chaînes de caractères :
il n'est pas possible d'utiliser cette méthode sur un tuple ou une liste.
Vérifier l'appartenance d'un caractère
Il est possible de vérifier si un caractère appartient à une chaîne de caractères
à l'aide de l'opérateur in
.
Cet opérateur renvoie True
si le caractère est présent dans la chaîne,
et False
sinon.
Contrairement à la méthode find
,
cet opérateur fonctionne aussi sur les tuples et les listes,
comme nous allons le voir dans la suite de cette section.
! Remarque
En Python, pour noter la négation de l'opérateur in
,
on peut utiliser l'opérateur not
directement
devant l'opérateur in
, comme dans l'exemple suivant :
Cette notation est plus lisible que la notation not "o" in chaine
,
qui est également valide mais moins naturelle.
Passage en majuscule et minuscule
Il est possible de passer une chaîne de caractères en majuscule
ou en minuscule à l'aide des méthodes upper
et lower
.
Les méthodes upper
et lower
retournent des copies de la chaîne de caractères,
avec les caractères en majuscule ou en minuscule.
Les tuples
Intéressons nous maintenant aux tuples. Alors que les chaînes de caractères sont des séquences de caractères, les tuples sont des séquences de valeurs qui peuvent être de différents types. Ils sont définis à l'aide de parenthèses et les valeurs sont séparées par des virgules. Les opérations que nous avons vues sur les chaînes de caractères sont, à quelques exceptions près, aussi valables pour les tuples.
Les tuples sont capables de stocker des valeurs de différents types. Par exemple, le tuple suivant contient un entier, une chaîne de caractères et un booléen.
À noter que les tuples peuvent même contenir d'autres séquences de valeurs, comme d'autres tuples par exemple.
Déconstruction d'un tuple
Il est possible de déconstruire un tuple à l'aide de l'instruction
d'affectation, en mettant sur la droite de l'opérateur =
le tuple à déconstruire et sur la gauche les variables
auxquelles affecter les valeurs du tuple, séparées par des virgules.
Il est possible de ne pas utiliser toutes les valeurs du tuple
lors de la déconstruction, en utilisant un underscore (_
)
pour les valeurs que l'on ne veut pas utiliser.
Il est possible de déconstruire un tuple directement dans une boucle for
,
comme dans l'exemple suivant.
Rechercher une valeur
Il est possible de rechercher une valeur dans un tuple
à l'aide de la méthode index
.
Cette méthode renvoie l'indice de la première valeur du tuple
qui correspond à la valeur recherchée.
Si la valeur n'est pas trouvée, la méthode renvoie une erreur.
Pour éviter cette erreur, il est possible de vérifier si la valeur est présente
dans le tuple à l'aide de l'opérateur in
avant d'appeler la méthode index
.
Les listes
Les listes sont des séquences de valeurs qui sont similaires aux tuples. Elles sont définies à l'aide de crochets et les valeurs sont séparées par des virgules. Les opérations que nous avons vues sur les tuples, ainsi que la plupart des opérations que nous avons vues sur les chaînes de caractères, sont aussi valables pour les listes.
Cependant, contrairement aux chaînes de caractères et aux tuples, les listes sont des séquences mutables. Cela signifie que les éléments d'une liste peuvent être modifiés, et la liste peut être agrandie ou réduite, le tout sans avoir à réaffecter la variable contenant la liste.
Modification d'éléments
Pour modifier un élément d'une liste liste
à un indice indice
, on utilise la notation
liste[indice] = valeur
, où valeur
est la nouvelle valeur
à affecter à l'élément.
Notez que le code ci-dessus modifie la liste liste_exemple
.
La variable liste_exemple
n'est pas réaffectée
(à aucun moment on ne fait liste_exemple =
),
mais la liste à laquelle elle fait référence a cependant été modifiée.
Ajout d'éléments
Notez que la méthode append
modifie la liste.
La valeur retournée par la méthode est None
.
Il est également possible d'ajouter un élément à une liste
à un indice donné à l'aide de la méthode insert
.
La méthode prend deux arguments : l'indice à laquelle ajouter l'élément,
et la valeur de l'élément.
Finalement, il est possible d'ajouter tous les éléments d'une liste
à la fin d'une autre liste à l'aide de la méthode extend
,
comme dans l'exemple suivant :
Aliasing
Il est important de comprendre que lorsque l'on affecte une liste à une variable, la variable ne contient pas directement la liste, mais une ce qu'on appelle une référence à la liste. Comme les listes sont des séquences mutables, il est donc possible de modifier la liste sans avoir à réaffecter la variable. Techniquement, la variable contient une référence à la liste, et cette référence est n'est pas modifiée lorsqu'on modifie la liste, uniquement la liste elle-même.
Dans le cas où deux variables (ou plus) font référence à la même liste en mémoire, on dit que les variables sont aliasées. Dans ce cas, si l'on modifie la liste à l'aide d'une des variables, alors la liste est modifiée pour toutes les variables qui font référence à la liste.
Dans le code ci-dessus, la variable liste_exemple_alias
fait référence à la même liste que la variable liste_exemple
.
Si on modifie la liste à l'aide de liste_exemple_alias
,
alors la liste est modifiée pour liste_exemple
aussi.
! Remarque
L'aliasing peut être source de confusion et de bugs. À cause de l'aliasing, il est possible de modifier une liste dans une partie du code sans s'en rendre compte, ce qui peut causer de nombreux problèmes et maux de tête.
Copie de listes
Pour copier une liste et non pas faire référence à la même liste,
on peut utiliser la méthode copy
.
Alternativement, on peut aussi noter liste[:]
,
qui retourne la sous-liste de liste
allant du début jusqu'à la fin.
Dans le code ci-dessus, la variable liste_exemple_copie
fait référence à une copie de la liste originale.
Si on modifie la liste à l'aide de liste_exemple_copie
,
alors la liste originale n'est pas modifiée.
Copie profonde
Dans le cas où la liste contient des listes, la copie de la liste ne copie pas les listes contenues dans la liste. La copie de la liste ne fait que copier les références aux listes. Cela signifie que si on modifie une liste contenue dans la liste, alors la liste originale est modifiée.
Dans le code ci-dessus, malgré la copie de la liste, la liste originale est modifiée. Cela est dû au fait que la copie de la liste ne copie pas les listes contenues dans la liste, mais seulement les références aux listes.
Pour copier une liste et ses listes contenues,
on peut utiliser la méthode deepcopy
du module copy
.
Pour cela, il faut importer la fonction avant de pouvoir l'utiliser.
Nous parlerons de modules dans la prochaine section.
✎ Auto-évaluation
La longueur d'une liste peut être obtenue en utilisant la fonction .
✎ Auto-évaluation
Pour accéder à un élément d'une séquence sequence
en fonction
de son indice indice
, on utilise la notation .
L'indice du premier élément d'une séquence est , et l'indice du dernier élément est .
✎ Auto-évaluation
Pour noter une liste, on utilise les , alors que pour noter un tuple, on utilise les . Dans les deux cas, les éléments sont séparés par des .
✎ Auto-évaluation
L'opérateur permet de vérifier si un élément est présent dans une séquence.
✎ Auto-évaluation
Contrairement aux chaînes de caractères et aux tuples, les listes sont des séquences , ce qui signifie qu'on peut les modifier après leur création.
Lorsque deux variables font référence à la même liste, on dit que les variables sont .
✎ Auto-évaluation
Pour ajouter un élément à la fin d'une liste, on utilise la méthode , qui prend comme argument l'élément à ajouter.
Pour ajouter plusieurs éléments à la fin d'une liste, on utilise la méthode , qui prend comme argument une liste d'éléments à ajouter.
Finalement, pour ajouter un élément à une position donnée, on utilise la méthode , qui prend comme arguments la position et l'élément à ajouter.
La valeur de retour de ces méthodes est toujours .
Dans cette section, nous avons vu comment créer et manipuler des séquences de valeurs en Python. En particulier, nous avons abordé les chaînes de caractères, les tuples et les listes.
Les listes sont les premières valeurs mutables que nous voyons en Python. Ces valeurs peuvent être modifiées après leur création, et ce sans devoir réaffecter une variable. Nous aurons l'occasion à l'avenir de voir d'autres types de valeurs mutables. Cette capacité de modifier des valeurs est très pratique, mais elle peut aussi être source de bugs.
Dans la prochaine section, nous allons voir comment utiliser des modules en Python.