Tuples, dictionnaires et ensembles en Python : cours et exercices corrigés
Tuples (création, déballage, immuabilité, renvoi de plusieurs valeurs), dictionnaires (clés, valeurs, ajout, test d'appartenance, parcours, comptage d'occurrences, regroupement), coût des opérations usuelles, et pour le Maroc les ensembles (set) et leurs opérations.
- 17méthodes
- 35exercices corrigés
- 4problèmes
- 20pièges
- 41figures
Un dictionnaire Python associe à chaque clé une valeur : d[c] lit la valeur de la clé c, d[c] = v la crée ou la remplace, c in d teste la présence d'une clé, chacun en temps constant en moyenne, quand x in L sur une liste fait jusqu'à comparaisons. Un tuple est une suite de valeurs qui ne se modifie pas : il range un enregistrement figé, sert de clé composée et porte les résultats multiples d'une fonction, qu'on récupère par dépaquetage. Ce chapitre d'informatique commune de première année, au programme de MPSI, PCSI, PTSI, TSI et TPC, au Maroc et en France, écrit en un seul parcours les algorithmes de base sur les dictionnaires : compter des occurrences, cumuler un total par clé, regrouper, trouver la clé de plus grande valeur, inverser, détecter un doublon en en moyenne au lieu de . Les exercices et problèmes reprennent des questions des sujets du CNC, de CCINP, de Mines-Ponts et de X-ENS. Les ensembles (set), avec union et intersection, sont au programme marocain et sont traités dans une partie qui lui est propre.
Ce que tu sauras faire
Une liste range des valeurs dans l'ordre ; elle ne suffit pas à tout. Une pesée enregistrée doit rester telle qu'elle a été notée ; un producteur doit se retrouver par son code sans relire tout le registre. Ce chapitre présente deux types qui répondent à ces besoins, le tuple et le dictionnaire, puis les algorithmes de base qui s'écrivent avec un dictionnaire. À la fin de ce chapitre, tu dois savoir :
- créer et lire un tuple, et expliquer pourquoi il ne se modifie pas ;
- dépaqueter un tuple, renvoyer plusieurs valeurs et parcourir une liste de couples ;
- créer un dictionnaire, lire, ajouter et modifier une valeur sans erreur de clé, tester une clé et parcourir le dictionnaire ;
- dire quelles clés sont permises et ce que coûtent les opérations ;
- compter des occurrences, cumuler un total par clé, regrouper, trouver la clé de plus grande valeur, inverser un dictionnaire, chacun en un seul parcours ;
- choisir la structure adaptée à un problème.
L'essentiel : Les dictionnaires Extrait gratuit
- Associe à chaque clé une valeur ; une clé n'apparaît qu'une fois ; deux clés peuvent avoir la même valeur.
{}(vide),{c1: v1, c2: v2};d[c]lit (clé absente :KeyError) ;d[c] = vcrée ou remplace ; pas d'append.c in dteste les clés ;len(d)compte les clés.for c in d(commefor c in d.keys()) parcourt les clés,d[c]donne la valeur ;for (c, v) in d.items()parcourt les couples. Ordre : celui de la première insertion. Pas d'ajout de clé pendant le parcours.e = dest un alias ;d.copy()est une copie superficielle (une valeur liste reste partagée).- Clés permises : nombres, chaînes, tuples de tels objets ; jamais de liste. Éviter les flottants calculés ;
1,1.0etTruesont la même clé.
Une méthode du chapitre Extrait gratuit
L'énoncé demande combien de fois apparaît chaque valeur, les effectifs, les fréquences, un histogramme, la valeur la plus fréquente.
Si les valeurs sont des entiers de 0 à , une liste de compteurs ; sinon un dictionnaire, qui n'a de clé que pour les valeurs rencontrées. Un seul parcours : en moyenne.
- Créer le dictionnaire vide.
- Pour chaque élément : s'il est déjà une clé, ajouter 1 ; sinon, créer la clé avec 1.
- Renvoyer le dictionnaire après la boucle.
d = {}
for x in L:
if x in d:
d[x] = d[x] + 1
else:
d[x] = 1
« Un seul parcours de la liste ; chaque tour fait un test et une écriture en temps constant en moyenne : le coût est en . »
Les chiffres d'un numéro de bon de livraison, "2026111407", comptés par un dictionnaire, puis par une liste de dix compteurs (les chiffres sont des entiers de 0 à 9).
num = "2026111407"
d = {}
for c in num:
if c in d:
d[c] = d[c] + 1
else:
d[c] = 1
print(d)
C = [0] * 10
for c in num:
C[int(c)] = C[int(c)] + 1
print(C)
Le programme affiche :
{'2': 2, '0': 2, '6': 1, '1': 3, '4': 1, '7': 1}
[2, 3, 2, 0, 1, 0, 1, 1, 0, 0]
Les deux résultats disent la même chose : deux 0, trois 1, deux 2. Le dictionnaire n'a pas de clé pour les chiffres absents ; la liste a une case nulle pour chacun.
- Oublier le cas de la première occurrence :
KeyError. Les correcteurs du concours X-ENS (rapport 2018, informatique commune) écrivent : « Il faut penser à traiter à part le cas où le dictionnaire ne comporte pas encore d'entrée pour la valeur à ajouter. » - Mettre le
returndans la boucle. - Compter chaque valeur par un parcours complet : comparaisons au lieu de .
Exercices 7, 8, 10 et 25, problème 1.
Un exercice corrigé Extrait gratuit
On a relevé les valeurs suivantes : L = [-5.2, 15, 9, 2, 0, 0, 9, 9, -5.2].
- Calculer le dictionnaire des nombres d'occurrences avec
compte_occurrences(cours, section 7.1), et donner la trace : l'état du dictionnaire après chaque tour. - Énoncer l'invariant de la boucle et en déduire que le résultat est juste.
- Pourquoi la liste de compteurs du chapitre « Listes et algorithmes de recherche » (un compteur par valeur entière de 0 à ) ne convient-elle pas ici ?
Question A. (Question ajoutée.) Que renvoie compte_occurrences([10, 12, 10.0, 8.2, 10]) ? Expliquer la clé obtenue pour 10.
- Méthode 8 : une clé par valeur rencontrée, créée à 1 la première fois, augmentée de 1 ensuite.
- Méthode 14 : l'invariant porte sur les premiers éléments.
- Question A : les nombres
10et10.0sont égaux.
Le comptage par dictionnaire ne demande pas de connaître les valeurs à l'avance : une clé n'est créée que pour une valeur rencontrée. Ici les valeurs sont négatives et flottantes : impossible de les prendre pour indices d'une liste. Pour la question A, deux nombres égaux sont la même clé, et la clé garde la forme sous laquelle elle a été créée.
L = [-5.2, 15, 9, 2, 0, 0, 9, 9, -5.2]
print(compte_occurrences(L))
Le programme affiche :
{-5.2: 2, 15: 1, 9: 3, 2: 1, 0: 2}
Trace (produite par programme) :
| tour | élément lu | dictionnaire après le tour |
|---|---|---|
| 1 | -5.2 |
{-5.2: 1} |
| 2 | 15 |
{-5.2: 1, 15: 1} |
| 3 | 9 |
{-5.2: 1, 15: 1, 9: 1} |
| 4 | 2 |
{-5.2: 1, 15: 1, 9: 1, 2: 1} |
| 5 | 0 |
{-5.2: 1, 15: 1, 9: 1, 2: 1, 0: 1} |
| 6 | 0 |
{-5.2: 1, 15: 1, 9: 1, 2: 1, 0: 2} |
| 7 | 9 |
{-5.2: 1, 15: 1, 9: 2, 2: 1, 0: 2} |
| 8 | 9 |
{-5.2: 1, 15: 1, 9: 3, 2: 1, 0: 2} |
| 9 | -5.2 |
{-5.2: 2, 15: 1, 9: 3, 2: 1, 0: 2} |
-
Invariant : après tours, les clés de
dsont exactement les valeurs rencontrées parmi les premiers éléments, et pour chacune,d[x]est son nombre d'occurrences parmi ces éléments. Il est vrai avant la boucle (, dictionnaire vide). S'il est vrai après tours, le tour suivant litx = L[t]: sixest déjà une clé, son compte augmente de 1 ; sinon la clé est créée avec le compte 1 ; les autres comptes ne changent pas. Il est donc vrai après tours. En sortie, :dcompte toute la liste. -
Les valeurs
-5.2et15ne sont pas des indices de liste : un indice est un entier positif ou nul, et-5.2n'est même pas entier. Une liste de compteurs ne convient que pour de petits entiers positifs connus d'avance.
Question A.
print(compte_occurrences([10, 12, 10.0, 8.2, 10]))
Le programme affiche :
{10: 3, 12: 1, 8.2: 1}
10.0 == 10 vaut True : le flottant 10.0 est compté avec l'entier 10, et la clé garde la forme de sa création, l'entier 10. Un affichage {10.0: 3, ...} serait donc faux.
Interprétation : la liste de 9 valeurs n'a que 5 valeurs distinctes ; 9 est la plus fréquente, 3 fois.
Le comptage par dictionnaire marche pour toutes les valeurs permises comme clés, en un parcours ; son invariant se rédige en trois temps. Voir les méthodes 8 et 14.
Le cours détaillé, toute la fiche « L'essentiel », 17 méthodes, 20 pièges corrigés, la carte mentale, 35 exercices corrigés, 4 problèmes de concours, les fiches à mémoriser et l'assistant qui répond à tes questions. Les trois premiers chapitres de chaque matière sont offerts avec un compte d’essai gratuit.
Ouvrir l'essai gratuitVoir les offresPlan du cours
- 1. Ranger des données qui vont ensemble
- 1.1 Le problème
- 1.2 Le registre du cours
- 2. Les tuples
- 2.1 Définition
- 2.2 Opérations
- 2.3 Un tuple ne se modifie pas
- 2.4 Liste ou tuple
- 3. Le dépaquetage
- 3.1 Affectation multiple
- 3.2 Renvoyer plusieurs valeurs
- 3.3 Une liste de tuples comme table de données
- 4. Les dictionnaires
- 4.1 Le problème
- 4.2 Créer et lire
- 4.3 Ajouter ou modifier
- 4.4 Tester une clé, compter les clés
- 4.5 Parcourir
- 4.6 Copier
- 5. Quelles clés ?
- 5.1 La règle
- 5.2 Des clés composées
- 5.3 Deux pièges sur les clés
- 6. Ce que coûtent les opérations
- 6.1 Ce que l'on admet
- 6.2 Une mesure
- 6.3 Conséquence : un doublon en un parcours
- 7. Les algorithmes de base sur les dictionnaires
- 7.1 Compter les occurrences
- 7.2 Cumuler un total par clé
- 7.3 Regrouper
- 7.4 La clé de plus grande valeur
- 7.5 Inverser
- 7.6 D'autres usages
- 8. Choisir sa structure
- 8.1 Un tableau de décision
- 8.2 Des structures imbriquées
- 8.3 Ce que les sujets fournissent
- 9. Les ensembles
- 9.1 Définition
- 9.2 Opérations
- 9.3 Union, intersection, différence
- 9.4 Applications
- 10. Autres fonctions du programme marocain
- 10.1 Sur les tuples
- 10.2 Sur les dictionnaires
Les méthodes du chapitre
Chaque méthode est une fiche : quand l'utiliser, le rappel de cours, les étapes, la rédaction attendue sur la copie, un exemple traité, les erreurs à éviter.
- Choisir entre liste, tuple et dictionnaire
- Créer et lire un tuple sans erreur
- Renvoyer plusieurs valeurs et les récupérer par un seul dépaquetage
- Parcourir une liste de couples ou de triplets en dépaquetant dans la boucle
- Lire et écrire dans un dictionnaire sans erreur de clé
- Parcourir un dictionnaire
- Choisir une clé permise, composer une clé par un tuple
- Compter des occurrences en un seul parcours
- Cumuler un total par clé
- Regrouper des éléments par clé dans un dictionnaire de listes
- Trouver la clé de plus grande valeur, avec la règle des ex aequo
- Inverser un dictionnaire
- Retenir les éléments déjà vus
- Prouver un parcours de dictionnaire et justifier son coût
- Copier un dictionnaire sans alias
- Utiliser un ensemble
- Employer les fonctions du programme marocain
Les exercices corrigés
Chaque exercice a ses indications, sa correction rédigée et ce qu'il faut en retenir.
Application directe (14)
- Des tuples à la main
- Degrés, minutes, secondes
- Rectangle, milieu, point intérieur
- Séparer abscisses et ordonnées
- Le maximum et sa place dans une grille
- Une bibliothèque en triplets
- Lire une table de fréquences
- Occurrences et probabilités d'un signal
- Premiers pas dans un dictionnaire de stock
- Compter des relevés
- Le morse dans les deux sens
- Les touches d'un clavier
- Des ensembles à la main
- Les valeurs distinctes d'un signal
Entraînement (16)
- Distances provisoires et plus petite clé
- Un jeu de semailles en dictionnaire
- Chemins, sauts et bonus
- Deux clés en couples
- Chiffres romains
- Un polynôme creux
- Regrouper les chiffres d'un numéro
- Liste ou dictionnaire : mesurer
- Les élèves par mois de naissance
- Fusionner deux stocks
- Les fiches des producteurs
- Quatre programmes qui échouent
- Compter tous les caractères d'un texte
- Les couples d'un arbre de codage
- Des motifs sans doublons
- Les fonctions du programme marocain
Approfondissement (5)
- Élaguer un arbre de prédécesseurs
- Alignements et score
- Le dictionnaire d'al-Khalil en nombres
- Une grille creuse
- Motifs communs à toutes les lignes
Les problèmes de concours
Des extraits de sujets réels, corrigés en entier, avec la durée conseillée et les méthodes mobilisées.
- Histogramme, entropie et égalisation d'une image
- Gestion de randonnées : points, altitudes, dénivelés
- Classer les obstacles détectés par une caméra
- Résolution d'une grille de Sudoku
Questions fréquentes
Quelle différence entre une liste et un tuple en Python ?
Un tuple ne se modifie pas : p[2] = 12400 sur un tuple provoque une TypeError, et pour changer une valeur on fabrique un nouveau tuple. Une liste range une collection qui grandit ou change ; un tuple range un enregistrement figé dont chaque place a un sens, comme une pesée (producteur, variété, poids, lot), un point ou une date. Un tuple dont les valeurs sont des nombres, des chaînes ou d'autres tels tuples peut être une clé de dictionnaire, une liste jamais. Un tuple à un seul élément s'écrit (5,) : (5) est l'entier 5. Un tuple qui contient une liste reste le même, mais la liste, elle, peut changer.
Comment compter les occurrences avec un dictionnaire en Python ?
On parcourt la liste une seule fois : pour chaque élément x, si x in d, on écrit d[x] = d[x] + 1, sinon d[x] = 1, et l'on renvoie d après la boucle. Sur la liste ['V03', 'V01', 'V05', 'V03', 'V03', 'V02', 'V01', 'V03'], on obtient {'V03': 4, 'V01': 2, 'V05': 1, 'V02': 1}. Sans le cas de la première occurrence, d[x] + 1 lit une clé absente et le programme s'arrête sur KeyError. Le coût est en en moyenne, quand compter chacune des valeurs distinctes par un parcours complet coûterait comparaisons. Au programme marocain, d[x] = d.get(x, 0) + 1 fait le même travail en une ligne.
Comment parcourir un dictionnaire en Python ?
for c in d parcourt les clés, comme for c in d.keys(), et d[c] donne la valeur de chacune ; for (c, v) in d.items() parcourt les couples (clé, valeur). Sans items(), for (c, v) in d reçoit les clés et tente de dépaqueter chacune : ValueError, ou pire, aucune erreur si les clés sont des couples. Les clés viennent dans l'ordre de leur première insertion, garanti depuis Python 3.7, mais on ne s'appuie pas sur cet ordre pour un résultat. keys() et items() se parcourent et ne s'indexent pas. Ajouter des clés pendant le parcours arrête le programme sur RuntimeError. Au programme marocain, d.values() parcourt les valeurs.
Quelle est la complexité des opérations sur un dictionnaire Python ?
On admet que c in d, d[c], d[c] = v et len(d) se font en temps constant en moyenne, quel que soit le nombre de clés ; le parcours et la copie d.copy() coûtent un temps proportionnel au nombre de clés. Sur une liste, x in L fait jusqu'à comparaisons. Dans la mesure du chapitre, 2 000 tests d'appartenance prennent 12,7 s dans une liste d'un million d'entiers, et 0,0005 s dans un dictionnaire qui a ces entiers pour clés. Détecter un doublon avec un dictionnaire des éléments déjà vus coûte au pire tests, au lieu de comparaisons par deux boucles imbriquées, soit 499 500 pour . En France, le principe qui permet ces coûts, le hachage, est vu en deuxième année.
Quelles clés peut-on utiliser dans un dictionnaire Python ?
Une clé est un nombre, une chaîne, ou un tuple dont les valeurs sont elles-mêmes permises comme clés. Une liste ou un dictionnaire n'est jamais une clé : d[[10, 15]] = 5 provoque une TypeError, de même qu'un tuple qui contient une liste. Les valeurs, elles, peuvent être de tout type. Pour une donnée qui dépend de deux informations, on prend un couple : grille[(2, 3)]. On évite les flottants calculés, car 0.1 + 0.2 ne retrouve pas la clé 0.3, et l'on ne mélange pas nombres et booléens : 1, 1.0 et True sont la même clé.
Comment renvoyer plusieurs valeurs d'une fonction Python ?
La fonction renvoie un tuple, return (x, y), et l'appelant le dépaquette en une seule affectation : (p, v, g, l) = lire_pesee(ligne). Il faut autant de variables que de valeurs, sinon le programme s'arrête sur ValueError (too many ou not enough values to unpack). On appelle la fonction une seule fois : écrire lire_pesee(ligne)[0] puis lire_pesee(ligne)[2] refait tout le travail à chaque appel. L'échange a, b = b, a est lui aussi un dépaquetage, et for (p, v, g, l) in R dépaquette chaque quadruplet d'une liste dans l'en-tête de la boucle.
Comment y accéder
Ce chapitre fait partie de l'accès complet. Les trois premiers chapitres de chaque matière (deux par bloc en économie et droit, en management et gestion) sont offerts avec un compte d'essai gratuit. Créer un compte d'essai ou se connecter. Pour l'accès complet et les tarifs, vois les offres.