Les structures de données
Une variable retient une valeur. Que fait-on quand on en as trente ?
Écrire note1, note2, note3 jusqu'à note30 est possible, et c'est une impasse : impossible d'en faire la moyenne sans écrire trente additions, impossible d'en ajouter une trente et unième sans modifier le programme. Il faut ranger plusieurs valeurs sous un seul nom. C'est l'objet de ce chapitre.
Ce qu'on va apprendre
- Ranger une suite de valeurs dans une liste, et la parcourir.
- Associer une valeur à une clé dans un dictionnaire.
- Manipuler du texte comme une suite de caractères.
- Comprendre pourquoi deux étiquettes sur la même liste posent un problème.
La liste : une suite de valeurs
Une liste est une collection ordonnée et modifiable de valeurs, écrite entre crochets. Elle peut contenir des nombres, du texte, ou un mélange.
Trois valeurs suffisent à voir l'intérêt : la moyenne s'écrit pareil pour quatre notes ou pour trois mille.
Atteindre un élément
Chaque élément a un indice, et les indices commencent à zéro.
0 est la source d'erreur numéro un sur les listes. Une liste de trois éléments a pour dernier indice 2, pas 3.La règle : le dernier indice vaut toujours
len(liste) - 1. Ou plus simplement, liste[-1], qui compte depuis la fin et ne se trompe jamais.
Le bloc suivant est faux exprès.
IndexError: list index out of range. Il y a bien trois notes, mais leurs indices sont 0, 1 et 2. Remplacer 3 par 2, ou mieux par -1, et relance.
Modifier
Une liste est mutable : on peut changer, ajouter, retirer après coup.
append, remove, pop et len suffisent pour presque tout. Il en existe d'autres, insert pour placer à un endroit précis, extend pour ajouter plusieurs éléments, clear pour vider : on les chercheras le jour où on en auras besoin.
Parcourir et calculer
Le dictionnaire : associer une clé à une valeur
Une liste de notes ne dit pas à qui appartient chaque note. On serait tenté de tenir deux listes en parallèle, prenoms et notes, et de les faire correspondre par leur indice. C'est fragile : il suffit d'en trier une pour tout casser.
Un dictionnaire associe des clés à des valeurs, entre accolades, avec la syntaxe cle: valeur. On accède à une valeur par sa clé, jamais par un indice.
Par sa position, ou parce que je veux toutes les parcourir dans l'ordre : c'est une liste.
Par un identifiant, un nom, un code, une date : c'est un dictionnaire.
Le symptôme qui doit alerter : deux listes de même longueur qu'on parcourt avec le même indice. Cela veut presque toujours dire qu'un dictionnaire s'imposait.
Parcourir un dictionnaire
.keys() donne les clés, .values() les valeurs, .items() les paires. C'est .items() qu'on emploiera le plus.
La clé qui n'existe pas
KeyError: 'Zoe'. Demander une clé absente arrête le programme. Quand on n'est pas sûr, .get() répond sans planter, et accepte une valeur de repli.
notes.get("Zoe") renvoie None, qui signifie « rien », et non 0, qui est une note. Calculer avec None déclenche un TypeError.Quand la valeur sert à un calcul, donne toujours un repli :
notes.get("Zoe", 0). Quand on veut savoir si la clé existe, emploie in, c'est plus clair qu'une comparaison à None.
Le texte, une suite de caractères
Une chaîne se comporte presque comme une liste de lettres, à une différence près : elle est immuable. On peut la lire et en fabriquer de nouvelles, jamais changer une lettre en place.
Les deux méthodes qui servent le plus font le lien avec les listes : split() découpe un texte en liste, join() recolle une liste en texte.
mot.upper() ne change pas mot : il renvoie une nouvelle chaîne. Si on veut garder le résultat, il faut le ranger : mot = mot.upper().C'est l'inverse des listes, où
notes.append(15) modifie la liste elle-même et ne renvoie rien. Cette différence explique la moitié des surprises du chapitre.
Un tuple est une liste immuable, écrite entre parenthèses : coordonnees = (3, 7). On l'emploie pour des données fixes, et l'on peut le dépaqueter d'un coup avec x, y = coordonnees.
Deux étiquettes, une seule liste
Souvenons-nous du chapitre 2 : une variable est une étiquette collée sur une valeur. Avec les listes, cette image cesse d'être une commodité et devient indispensable.
equipe_b = equipe_a ne fabrique pas une deuxième liste : elle colle une deuxième étiquette sur la liste existante. Modifier la liste par l'une ou par l'autre revient au même, puisqu'il n'y en a qu'une.Pour obtenir une vraie copie indépendante :
equipe_b = equipe_a.copy().Ce comportement ne vaut que pour les valeurs modifiables, listes et dictionnaires. Avec un nombre ou un texte, la question ne se pose pas : on ne peut pas les modifier, donc on ne peut pas surprendre l'autre étiquette.
Le dessin ci-dessous montre la situation telle qu'elle est en mémoire, et non telle qu'on l'imagine. Il n'y a qu'une seule liste, et deux étiquettes pointées dessus.
L'image de la boîte, qui suffit tant qu'on manipule des nombres, cesse ici de fonctionner. Une variable n'est pas une boîte qui contient une valeur : c'est une étiquette collée sur un objet. Deux étiquettes sur le même objet, c'est une situation ordinaire, et la seule façon de la comprendre est de la voir.
Compter les occurrences est l'exercice type du dictionnaire, et celui où l'on se perd le plus vite : la clé change à chaque tour, et la valeur associée aussi. La trace le déroule.
| 1 | compte = {} |
| 2 | for c in "abraca": |
| 3 | if c in compte: |
| 4 | compte[c] = compte[c] + 1 |
| 5 | else: |
| 6 | compte[c] = 1 |
| 7 | print(compte) |
Variables
| compte | {} |
Le if c in compte distingue les deux seuls cas possibles : la lettre a déjà été vue, et il faut incrémenter ; ou c'est la première fois, et il faut créer l'entrée à 1. Oublier le else donne une erreur de clé absente au tout premier caractère, ce que la trace montre en s'arrêtant net.
Quelle structure choisir
| Structure | Écriture | Modifiable | Quand l'employer |
|---|---|---|---|
| Liste | [1, 2, 3] | oui | une suite de valeurs, parcourue ou indexée |
| Dictionnaire | {"a": 1} | oui | retrouver une valeur par un identifiant |
| Chaîne | "texte" | non | du texte |
| Tuple | (3, 7) | non | des valeurs fixes qui vont ensemble |
1.Quel est le dernier indice valide d'une liste de 5 éléments ?
2.Après a = [1, 2], b = a, b.append(3), que vaut a ?
3.Que renvoie {"x": 1}.get("y") ?
4.Que fait mot.upper() sur mot = "python" ?
5.Deux listes prenoms et notes de même longueur, parcourues avec le même indice. Que faudrait-il ?
À mettre en pratique
Le bulletin. À partir du dictionnaire ci-dessous, affiche la moyenne générale avec deux décimales, puis le nom du meilleur élève.
Afficher la solution
La moyenne se lit directement sur les valeurs : sum(notes.values()).
Pour le maximum, on emploie le schéma « préparer, parcourir, comparer » : une variable qui retient le meilleur trouvé jusqu'ici, initialisée à une valeur que tout dépassera. Python offre un raccourci, max(notes, key=notes.get), mais la boucle explicite est ce qu'on attend de soi en devoir, et c'est elle qui se transpose à tous les autres problèmes.
Synthèse
- Une liste range une suite de valeurs ; ses indices commencent à zéro.
- Le dernier indice vaut
len(liste) - 1, ou plus sûrementliste[-1]. append,remove,popetlencouvrent l'essentiel.- Un dictionnaire retrouve une valeur par une clé ;
.items()parcourt les paires. - Une clé absente déclenche un
KeyError: emploie.get(cle, repli)ou le testin. Nonesignifie « rien », ce n'est pas0.- Une chaîne est immuable : ses méthodes renvoient une nouvelle chaîne.
b = asur une liste ne copie pas : les deux étiquettes désignent la même liste. Il faut.copy().- Deux listes parallèles parcourues par le même indice : c'est un dictionnaire qu'il fallait.
Mettre en pratique
Indices, parcours, ajout et suppression.
- Lire une liste par indice1 · Débuter
- Suivre une liste qui se remplit1 · Débuter
- Total d'une série de mesures2 · Fonctions
- Moyenne d'une série de mesures2 · Fonctions
- Le plus petit relevé2 · Fonctions
- Compter les positifs2 · Fonctions
- Filtrer les valeurs paires2 · Fonctions
- Filtrer les pairs (autonome)3 · Confirmé
- Doubler chaque valeur2 · Fonctions
- Compter les occurrences2 · Fonctions
- Trouver la position d'une valeur3 · Confirmé
- Supprimer les doublons3 · Confirmé
- Fusionner deux listes2 · Fonctions
- Débogage : le maximum d'une liste2 · Fonctions
- Parcourir une série de relevés1 · Débuter
Découper, assembler et transformer du texte.
- Découper une chaîne1 · Débuter
- Lire une chaîne1 · Débuter
- Longueur d'une chaîne2 · Fonctions
- Tout en majuscules2 · Fonctions
- Majuscule à la première lettre2 · Fonctions
- Compter un caractère3 · Confirmé
- Compter les mots d'une phrase2 · Fonctions
- Répéter un motif2 · Fonctions
- Remplacer un caractère2 · Fonctions
- Extraire les initiales3 · Confirmé
- Extraire l'extension d'un fichier3 · Confirmé
- Débogage : mot de passe trop court2 · Fonctions
Associer des clés à des valeurs et les parcourir.
- Modifier un dictionnaire1 · Débuter
- Lire un dictionnaire1 · Débuter
- Créer une fiche2 · Fonctions
- Prix au catalogue2 · Fonctions
- Lire une valeur (ou rien)2 · Fonctions
- La pièce est-elle référencée ?2 · Fonctions
- Lister les références2 · Fonctions
- Lister les quantités2 · Fonctions
- Total du stock3 · Confirmé
- Compter chaque lettre3 · Confirmé
- Filtrer par quantité3 · Confirmé
- Inverser un annuaire3 · Confirmé
- Fusionner deux stocks3 · Confirmé
- Défi : le mot le plus fréquent4 · Avancé
- Débogage : le comptage reste à 13 · Confirmé
Listes de listes, grilles et matrices.
- Lire une matrice1 · Débuter
- Lire une grille1 · Débuter
- Garder les valeurs positives2 · Fonctions
- Aplatir une liste de listes3 · Confirmé
- Somme d'une grille3 · Confirmé
- Défi : moyennes par étudiant4 · Avancé
- Débogage : la somme s'arrête trop tôt3 · Confirmé