Aller au contenu
Réussir mon BTS SIO

Tape une notion, une commande ou le nom d'une épreuve.

Par exemple

Chapitre 518 minDébutant

Chaînes, listes et tuples en Python

Par Josselyn C., prof de BTS SIO. Mis à jour le .

À la fin de ce chapitre, tu sauras

  • extraire une partie d'une chaîne ou d'une liste avec les indices et les tranches ;
  • découper, nettoyer et rassembler des chaînes ;
  • ajouter, retirer et trier les éléments d'une liste ;
  • copier une liste sans piège et déballer un tuple.

3 exercices corrigés1 schéma

Une chaîne (str) est une suite de caractères, une liste (list) une suite modifiable de valeurs, un tuple (tuple) une suite non modifiable : ce sont les trois séquences de Python, et elles partagent la même façon d'accéder aux éléments par indices et par tranches. Ce chapitre présente les indices et les tranches, les méthodes des chaînes qui servent tous les jours (découper, nettoyer, rassembler), les opérations sur les listes, le tri, le parcours avec enumerate et zip, la copie d'une liste et le déballage des tuples.

Indices et tranches

Chaque élément d'une séquence a un indice, qui commence à 0. Les indices négatifs partent de la fin : -1 est le dernier élément. Une tranche s[debut:fin] extrait les éléments de debut inclus à fin exclu, comme range().

indiceindice négatif0123456-7-6-5-4-3-2-1SORBIERdébut 2 (inclus)fin 5 (exclu)nom[2:5] donne 'RBI'
Indices positifs, indices négatifs et tranche nom[2:5] : de l'indice 2 inclus à l'indice 5 exclu
python
>>> nom = "SORBIER"
>>> nom[0]
'S'
>>> nom[6]
'R'
>>> nom[-1]
'R'
>>> nom[2:5]
'RBI'
>>> nom[:3]
'SOR'
>>> nom[3:]
'BIER'
>>> nom[-3:]
'IER'
>>> nom[::-1]
'REIBROS'
>>> nom[7]
Traceback (most recent call last):
  File "<python-input-9>", line 1, in <module>
    nom[7]
    ~~~^^^
IndexError: string index out of range
ÉcritureCe qu'elle donne
s[i]L'élément d'indice i
s[-1]Le dernier élément
s[a:b]Les éléments de a inclus à b exclu
s[:b]Les b premiers éléments
s[a:]Tout à partir de l'indice a
s[-n:]Les n derniers éléments
s[::-1]La séquence à l'envers

Un indice hors de la séquence provoque une IndexError, mais une tranche, jamais : nom[5:50] renvoie simplement 'ER'.

Les méthodes des chaînes

Une chaîne est non modifiable : ses méthodes renvoient une nouvelle chaîne, sans toucher à l'originale. Voici celles qu'un script d'administration utilise sans arrêt :

python
>>> fqdn = "srv-fichiers.ad.sorbier.example"
>>> fqdn.split(".")
['srv-fichiers', 'ad', 'sorbier', 'example']
>>> fqdn.split(".", 1)
['srv-fichiers', 'ad.sorbier.example']
>>> fqdn.upper()
'SRV-FICHIERS.AD.SORBIER.EXAMPLE'
>>> fqdn.startswith("srv-")
True
>>> fqdn.endswith(".example")
True
>>> fqdn.find("sorbier")
16
>>> fqdn.replace("srv-", "")
'fichiers.ad.sorbier.example'
>>> "  PC-0042 \n".strip()
'PC-0042'
>>> "42".zfill(4)
'0042'
>>> " ; ".join(["srv-ad", "srv-ad2"])
'srv-ad ; srv-ad2'
>>> "PC-0042".isalnum(), "0042".isdigit()
(False, True)
>>> fqdn[0] = "S"
Traceback (most recent call last):
  File "<python-input-12>", line 1, in <module>
    fqdn[0] = "S"
    ~~~~^^^
TypeError: 'str' object does not support item assignment
MéthodeRôleUsage typique
split(sep)Découpe en listeLes champs d'une ligne, les morceaux d'un nom DNS
sep.join(liste)Rassemble une liste de chaînesConstruire une ligne CSV, une liste lisible
strip()Retire espaces et retours à la ligne aux deux boutsToute ligne lue dans un fichier ou saisie
lower(), upper()Minuscules, majusculesComparer sans tenir compte de la casse
replace(a, b)Remplace toutes les occurrencesCorriger un séparateur, anonymiser
startswith(), endswith()Teste le début ou la finFiltrer des noms de machines, des extensions
find(x)Indice de la première occurrence, -1 si absenteRepérer un mot (ou x in s pour un simple test)
zfill(n)Complète par des zéros à gaucheNuméros d'inventaire PC-0042
isdigit(), isalnum()Que des chiffres ? Que des lettres et chiffres ?Valider une saisie

fqdn[0] = "S" échoue : pour « modifier » une chaîne, on en construit une nouvelle, "S" + fqdn[1:]. Les chaînes de Python sont en Unicode : len("Chloé") vaut 5, et "é".upper() donne 'É'.

Les listes : ajouter, retirer, trier

Une liste s'écrit entre crochets ; elle peut contenir des valeurs de tous types, et elle se modifie sur place :

python
# listes.py : créer, modifier et parcourir une liste
serveurs = ["srv-ad", "srv-fichiers", "srv-gestion"]
serveurs.append("srv-journaux")        # ajoute à la fin
serveurs.insert(1, "srv-ad2")          # insère à l'indice 1
print(serveurs, len(serveurs))

serveurs.remove("srv-gestion")         # retire la première occurrence de cette valeur
dernier = serveurs.pop()               # retire et renvoie le dernier élément
print(dernier, serveurs)
print(serveurs[0], serveurs[-1], serveurs[1:3])
print("srv-ad2" in serveurs, serveurs.index("srv-fichiers"))

occupations = [31.7, 87.5, 93.0, 44.8]
print(sum(occupations), min(occupations), max(occupations))
print(sorted(occupations), occupations)      # sorted renvoie une nouvelle liste
occupations.sort(reverse=True)               # sort trie la liste elle-même
print(occupations)
text
['srv-ad', 'srv-ad2', 'srv-fichiers', 'srv-gestion', 'srv-journaux'] 5
srv-journaux ['srv-ad', 'srv-ad2', 'srv-fichiers']
srv-ad srv-fichiers ['srv-ad2', 'srv-fichiers']
True 2
257.0 31.7 93.0
[31.7, 44.8, 87.5, 93.0] [31.7, 87.5, 93.0, 44.8]
[93.0, 87.5, 44.8, 31.7]
OpérationEffet
liste.append(x)Ajoute x à la fin
liste.insert(i, x)Insère x à l'indice i
liste.remove(x)Retire la première occurrence de x (ValueError si absent)
liste.pop(), liste.pop(i)Retire et renvoie le dernier élément, ou celui d'indice i
liste.index(x)Indice de la première occurrence de x
x in listeTrue si x est dans la liste
len, sum, min, maxLongueur, somme, minimum, maximum
liste.sort()Trie la liste elle-même et renvoie None
sorted(liste)Renvoie une nouvelle liste triée, l'originale ne bouge pas

Parcourir avec enumerate et zip, trier avec une clé

python
# parcours.py : enumerate, zip et tri avec une clé
noms = ["srv-ad", "srv-fichiers", "srv-gestion", "srv-journaux"]
adresses = ["192.168.10.177", "192.168.10.178", "192.168.10.179", "192.168.10.180"]

for rang, nom in enumerate(noms, start=1):
    print(rang, nom)

for nom, ip in zip(noms, adresses):
    print(f"{nom:<14}{ip}")

volumes = [("srv-ad", 38), ("srv-fichiers", 437), ("srv-gestion", 112), ("srv-journaux", 186)]
par_taille = sorted(volumes, key=lambda v: v[1], reverse=True)
print(par_taille[:2])
print(sorted(noms, key=len))
text
1 srv-ad
2 srv-fichiers
3 srv-gestion
4 srv-journaux
srv-ad        192.168.10.177
srv-fichiers  192.168.10.178
srv-gestion   192.168.10.179
srv-journaux  192.168.10.180
[('srv-fichiers', 437), ('srv-journaux', 186)]
['srv-ad', 'srv-gestion', 'srv-fichiers', 'srv-journaux']

enumerate() donne le rang et l'élément à chaque tour, ce qui évite le for i in range(len(liste)) des autres langages. zip() avance dans deux listes en même temps et s'arrête à la plus courte.

Le paramètre key de sorted() dit selon quoi trier : une fonction appliquée à chaque élément. key=len trie les noms par longueur ; key=lambda v: v[1] trie les couples selon leur deuxième élément, la taille. Une lambda est une petite fonction anonyme d'une seule expression : lambda v: v[1] équivaut à une fonction qui reçoit v et renvoie v[1]. Avec reverse=True, le tri est décroissant, et la tranche [:2] garde les deux plus gros volumes.

Copier une liste

Une affectation b = a ne copie pas une liste : elle donne un deuxième nom à la même liste.

python
>>> a = [3, 8, 5]
>>> b = a
>>> b[0] = 99
>>> a
[99, 8, 5]
>>> c = a.copy()
>>> c[0] = 1
>>> a, c
([99, 8, 5], [1, 8, 5])

Modifier la liste par b modifie donc aussi ce que voit a. Pour une vraie copie, a.copy() (ou list(a), ou a[:]). Le cours Algorithmique illustre ce partage par un schéma (copier une liste). Le même mécanisme explique qu'une fonction qui reçoit une liste peut la modifier : elle reçoit la liste elle-même, pas une copie.

Les tuples et le déballage

Un tuple s'écrit entre parenthèses (ou juste avec des virgules). Comme une chaîne, il est non modifiable : on s'en sert pour un groupe de valeurs qui vont ensemble et ne changent pas, comme un enregistrement ou des coordonnées.

python
>>> poste = ("PC-0012", "192.168.10.71", "Comptabilité")
>>> poste[1]
'192.168.10.71'
>>> nom, ip, service = poste
>>> service
'Comptabilité'
>>> premier, *reste = ["srv-ad", "srv-ad2", "srv-fichiers"]
>>> reste
['srv-ad2', 'srv-fichiers']
>>> poste[1] = "192.168.10.72"
Traceback (most recent call last):
  File "<python-input-6>", line 1, in <module>
    poste[1] = "192.168.10.72"
    ~~~~~^^^
TypeError: 'tuple' object does not support item assignment

Le déballage range chaque élément d'une séquence dans une variable : nom, ip, service = poste. Il faut autant de variables que d'éléments, sauf avec l'étoile, qui ramasse le reste dans une liste. C'est le même mécanisme qui permet à une fonction de renvoyer plusieurs valeurs et à for nom, ip in zip(...) de recevoir deux variables à chaque tour.

Chaîne strListe listTuple tuple
Écriture"abc"[1, 2, 3](1, 2, 3)
ContenuDes caractèresToutTout
ModifiableNonOuiNon
UsageDu texteUne collection qui grandit ou changeUn enregistrement fixe, un retour multiple

Exercices

Exercice 1 sur 3 Découper une adresse IP Réussi À revoir

Prévois le résultat de chaque ligne, puis vérifie dans la console.

python
ip = "192.168.10.177"
octets = ip.split(".")
octets
int(octets[3]) + 1
".".join(octets[:3]) + ".0"
ip[:10]
ip.count(".")
Voir la réponseMasquer la réponse de l'exercice 1
python
>>> ip = "192.168.10.177"
>>> octets = ip.split(".")
>>> octets
['192', '168', '10', '177']
>>> int(octets[3]) + 1
178
>>> ".".join(octets[:3]) + ".0"
'192.168.10.0'
>>> ip[:10]
'192.168.10'
>>> ip.count(".")
3

split renvoie des chaînes : il faut int() pour calculer. octets[:3] garde les trois premiers octets, que join recolle avec des points. Pour de vrais calculs d'adresses (réseau, masque, appartenance), le module ipaddress fait tout cela sans erreur (chapitre 12).

Tu avais trouvé ?

Exercice 2 sur 3 Nettoyer une liste de noms Réussi À revoir

Un collègue a saisi [" SRV-AD ", "srv-ad2\n", "Srv-Fichiers", "srv-gestion "]. Écris un script qui produit la liste des noms sans espaces, en minuscules et triés, puis les affiche séparés par des virgules.

Voir la réponseMasquer la réponse de l'exercice 2
python
# ex_noms.py : nettoyer et trier une liste de noms de machines
saisis = [" SRV-AD ", "srv-ad2\n", "Srv-Fichiers", "srv-gestion  "]

propres = []
for nom in saisis:
    propres.append(nom.strip().lower())

propres.sort()
print(propres)
print(", ".join(propres))
text
['srv-ad', 'srv-ad2', 'srv-fichiers', 'srv-gestion']
srv-ad, srv-ad2, srv-fichiers, srv-gestion

strip() retire les espaces et le \n, lower() uniformise la casse, sort() trie sur place. Le chapitre 6 écrit la même boucle en une ligne avec une compréhension de liste.

Tu avais trouvé ?

Exercice 3 sur 3 Mettre en forme les arrivées Réussi À revoir

Les ressources humaines envoient des lignes au format Prenom;Nom;Service;Fonction :

python
lignes = [
    "Théo;Marchal;Logistique;Préparateur",
    "Inès;Roux;Comptabilite;Assistante comptable",
    "Zoë;N'Diaye;Logistique;Cariste",
]

Affiche pour chacune NOM Prénom (Fonction, Service), le nom en majuscules.

Voir la réponseMasquer la réponse de l'exercice 3
python
# ex_arrivees.py : mettre en forme des lignes « Prenom;Nom;Service;Fonction »
lignes = [
    "Théo;Marchal;Logistique;Préparateur",
    "Inès;Roux;Comptabilite;Assistante comptable",
    "Zoë;N'Diaye;Logistique;Cariste",
]

for ligne in lignes:
    prenom, nom, service, fonction = ligne.split(";")
    print(f"{nom.upper()} {prenom} ({fonction}, {service})")
text
MARCHAL Théo (Préparateur, Logistique)
ROUX Inès (Assistante comptable, Comptabilite)
N'DIAYE Zoë (Cariste, Logistique)

Le déballage du split(";") donne un nom à chaque champ : plus lisible que champs[0], champs[1]… Si une ligne avait un champ de trop ou de moins, le déballage lèverait une ValueError : un vrai fichier se lit avec le module csv, qui gère aussi les guillemets (chapitre 7).

Tu avais trouvé ?

Chapitre terminé !

Fais les 3 exercices avant de passer à la suite : c'est en t'entraînant que tout se fixe.

chapitres
–
de série
–
du cours
–
Chapitre suivant : Dictionnaires, ensembles et compréhensionsRevoir le sommaire du cours