11 - Dictionnaires
Exercice 0 : QCM – vérification des prérequis
Pour chaque question, une seule réponse est correcte.
1. Quelle structure Python associe des clés à des valeurs ?
- A. Une liste
- B. Un tuple
- C. Un dictionnaire
- D. Un ensemble (set)
Correction
Réponse : C. Un dictionnaire (dict) est une collection de paires clé/valeur. On accède à une valeur par sa clé (et non par un indice numérique comme pour les listes).
- A est faux : une liste est une collection ordonnée indexée par des entiers.
- B est faux : un tuple est une séquence immutable indexée par des entiers.
- D est faux : un ensemble ne contient que des éléments uniques, sans valeurs associées.
2. Comment accéder à la valeur associée à la clé 'nom' dans d = {'nom': 'Alice', 'age': 17} ?
- A.
d[0] - B.
d['nom'] - C.
d.nom - D.
d(nom)
Correction
Réponse : B. On accède à une valeur par sa clé entre crochets : d['nom'] renvoie 'Alice'.
- A est faux :
d[0]chercherait une clé0(qui n’existe pas ici). Les dictionnaires ne sont pas indexés par position. - C est faux : cette syntaxe fonctionne pour les attributs d’objets, pas pour les dictionnaires.
- D est faux : les parenthèses servent aux appels de fonctions, pas à l’accès aux dictionnaires.
3. Que se passe-t-il si on écrit d['note'] = 15 avec d = {'nom': 'Alice'} ?
- A. Erreur car la clé
'note'n’existe pas - B. La paire
'note': 15est ajoutée au dictionnaire - C. Le dictionnaire est remplacé par
{'note': 15} - D. Rien ne se passe
Correction
Réponse : B. Si la clé n’existe pas, l’affectation crée une nouvelle entrée. Le dictionnaire devient {'nom': 'Alice', 'note': 15}. Si la clé existait déjà, sa valeur serait mise à jour.
- A est faux : contrairement aux listes (où l’indice doit exister), un dictionnaire accepte l’ajout de nouvelles clés par affectation.
- C est faux : seule la nouvelle paire est ajoutée, les anciennes sont conservées.
- D est faux : le dictionnaire est bien modifié.
4. Quels types Python peuvent servir de clé dans un dictionnaire ?
- A. Uniquement les chaînes de caractères
- B. Uniquement les entiers
- C. Tout type immutable (int, str, tuple, etc.)
- D. N’importe quel type, y compris les listes
Correction
Réponse : C. Les clés d’un dictionnaire doivent être immutables (non modifiables). Les types int, str, float, tuple et bool conviennent. Les listes et les dictionnaires, étant mutables, ne peuvent pas servir de clés.
- A est faux : les entiers, tuples et autres immutables fonctionnent aussi.
- B est faux : les chaînes sont les clés les plus courantes.
- D est faux :
d[[1, 2]] = 'test'provoque une erreurTypeError: unhashable type: 'list'.
Exemple travaillé : créer et parcourir un dictionnaire
Problème : on dispose des notes de trois élèves et on veut calculer la moyenne de la classe.
Étape 1. Créer le dictionnaire :
notes = {"Alice": 14, "Bob": 12, "Clara": 16}
Étape 2. Parcourir et afficher :
for nom, note in notes.items():
print(f"{nom} : {note}/20")
Étape 3. Calculer la moyenne :
total = 0
for note in notes.values():
total += note
moyenne = total / len(notes)
print(f"Moyenne : {moyenne}") # 14.0
Méthodes utiles :
d.keys()→ les clés ;d.values()→ les valeurs ;d.items()→ les paires (clé, valeur) ;cle in d→ teste si une clé existe.
Exercice 1
Soit le dictionnaire :
d = {'nom': 'Dupuis', 'prenom': 'Jacque', 'age': 30}
- Corriger l’erreur dans le prénom ‘Jacques’ à l’aide d’une instruction.
- Afficher la liste des clés du dictionnaire.
- Afficher la liste des valeurs du dictionnaire.
- Afficher la liste des paires clé/valeur du dictionnaire.
- Écrire une instruction qui affiche la phrase « Jacques Dupuis a 30 ans ».
Correction
d = {'nom': 'Dupuis', 'prenom': 'Jacque', 'age': 30}
# Corriger le prénom
d['prenom'] = 'Jacques'
# Afficher les clés
print(list(d.keys())) # ['nom', 'prenom', 'age']
# Afficher les valeurs
print(list(d.values())) # ['Dupuis', 'Jacques', 30]
# Afficher les paires clé/valeur
print(list(d.items())) # [('nom', 'Dupuis'), ('prenom', 'Jacques'), ('age', 30)]
# Afficher la phrase
print(f"{d['prenom']} {d['nom']} a {d['age']} ans")
# Jacques Dupuis a 30 ans
Exercice 2
- Créer un dictionnaire
elevesassociant des prénoms et des âges (pour environ cinq personnes). - Donner deux façons différentes d’itérer sur le dictionnaire et d’afficher les paires sous le format
"prenom a age ans".
Correction
eleves = {"Alice": 16, "Bob": 15, "Clara": 17, "David": 14, "Eva": 16}
# Méthode 1 : avec .items()
for prenom, age in eleves.items():
print(f"{prenom} a {age} ans")
# Méthode 2 : avec les clés
for prenom in eleves:
print(f"{prenom} a {eleves[prenom]} ans")
Exercice 3
Écrire une fonction qui prend en entrée une chaîne de caractères et retourne un dictionnaire indiquant, pour chaque mot, sa fréquence dans la chaîne fournie.
Correction
def frequences_mots(chaine):
"""Renvoie un dictionnaire des fréquences des mots."""
freq = {}
for mot in chaine.split():
if mot in freq:
freq[mot] += 1
else:
freq[mot] = 1
return freq
print(frequences_mots("le chat mange le poisson"))
# {'le': 2, 'chat': 1, 'mange': 1, 'poisson': 1}
Exercice 4
On dispose d’un dictionnaire associant à des noms de commerciaux d’une société le nombre de ventes qu’ils ont réalisées. Par exemple :
ventes = {"Dupont": 14, "Hervy": 19, "Geoffroy": 15, "Layec": 21}
- Écrire une fonction qui prend en entrée un tel dictionnaire et renvoie le nombre total de ventes dans la société.
- Écrire une fonction qui prend en entrée un tel dictionnaire et renvoie le nom du vendeur ayant réalisé le plus de ventes. Si plusieurs vendeurs sont ex-aequo sur ce critère, la fonction devra retourner le nom de l’un d’entre eux.
Correction
ventes = {"Dupont": 14, "Hervy": 19, "Geoffroy": 15, "Layec": 21}
def total_ventes(ventes):
"""Renvoie le nombre total de ventes."""
total = 0
for v in ventes.values():
total += v
return total
def meilleur_vendeur(ventes):
"""Renvoie le nom du vendeur ayant le plus de ventes."""
meilleur = None
max_ventes = 0
for nom, nb in ventes.items():
if meilleur is None or nb > max_ventes:
meilleur = nom
max_ventes = nb
return meilleur
print(f"Total : {total_ventes(ventes)}") # 69
print(f"Meilleur : {meilleur_vendeur(ventes)}") # Layec
Exercice 5
- Écrire une fonction
dico_vers_listequi convertit un dictionnaire en une liste de tuples (sans utiliser la fonctionitems()).
- Écrire une fonction
liste_vers_dicoqui convertit une liste de tuples en dictionnaire.
Correction
def dico_vers_liste(mon_dico): """Calcule une liste de paires (cle, valeur) à partir d"un dictionnaire.""" ma_liste = [] for cle in mon_dico: ma_liste.append((cle, mon_dico[cle])) return ma_listedef liste_vers_dico(ma_liste): """Calcule un dictionnaire à partir d"une liste de paires (cle, valeur).""" mon_dico = {} for paire in ma_liste: mon_dico[paire[0]] = paire[1] return mon_dico
Exercice 6
Écrire une fonction qui prend en entrée une chaîne de caractères comprenant, sur chaque
ligne, trois champs séparés par des caractères ';' (un numéro d’étudiant, un nom et un
prénom) et renvoie un dictionnaire dont les clés sont les numéros d’étudiants et
les valeurs sont, pour chaque numéro d’étudiant, une chaîne correspondant à la
concaténation des prénom et nom de la personne. On pourra tester la fonction avec la
chaîne suivante :
chaine_etudiants = """213615200;BESNIER;JEAN
213565488;DUPOND;MARC
214665555;DURAND;JULIE"""
Correction
def dico_etudiants(chaine):
liste_etudiants = chaine.split("\n")
d = {}
for etudiant in liste_etudiants:
liste_infos = etudiant.split(";")
d[liste_infos[0]] = liste_infos[2] + ' ' + liste_infos[1]
return d
print(dico_etudiants(chaine_etudiants))
Exercice 7
Écrire une fonction qui prend en entrée un dictionnaire associant à un nom une liste de notes et qui renvoie la liste des noms des personnes qui ont la moyenne la plus élevée (s’il y a des ex-aequo, cette liste contiendra plusieurs éléments, sinon, elle n’en contiendra qu’un) et la moyenne correspondante. On pourra utiliser le dictionnaire suivant pour tester la fonction ainsi écrite :
notes = {"Tom": [8, 10, 12], "Mila": [10, 9], "Alex": [], "Lina": [12, 10, 8]}
Exercice 8 - Gestion de bibliothèque
On considère le dictionnaire suivant qui recense les livres empruntables dans une bibliothèque.
livres = {
"Les misérables": ("Victor Hugo", 5),
"Le dernier des Mohicans": ("James F. Cooper", 0),
"Un animal doué de raison": ("Robert Merle", 6),
"Le grand Meaulnes": ("Alain Fournier", 1),
"Notre-dame de Paris": ("Victor Hugo", 4),
"Les Contemplations": ("Victor Hugo", 0),
}
On peut rechercher rapidement un livre à partir de son titre (clé du dictionnaire). On obtient alors l’auteur du livre ainsi que le nombre d’exemplaire(s) empruntable(s) en stock.
Par exemple :
print(livres['Notre-dame de Paris'])
('Victor Hugo', 4)
- Écrire un programme qui liste l’ensemble des noms d’auteurs du dictionnaire. On veillera à ce qu’il n’y ait pas de doublons.
- Écrire un programme qui liste l’ensemble des livres empruntables.
- Écrire une fonction
titres_auteurqui, étant donné un nom d’auteur, retourne l’ensemble des titres de livres écrits par cet auteur.
Correction
livres = {
"Les misérables": ("Victor Hugo", 5),
"Le dernier des Mohicans": ("James F. Cooper", 0),
"Un animal doué de raison": ("Robert Merle", 6),
"Le grand Meaulnes": ("Alain Fournier", 1),
"Notre-dame de Paris": ("Victor Hugo", 4),
"Les comtemplations": ("Victor Hugo", 0),
}
auteurs = [] for paire in livres.values(): if paire[0] not in auteurs: auteurs.append(paire[0]) print(paire[0])for titre, paire in livres.items(): if paire[1] != 0: print(titre)def titres_auteur(auteur): titres = [] for titre, paire in livres.items(): if paire[0] == auteur: titres.append(titre) return titres print(titres_auteur("Victor Hugo"))
Exercice 9 - Magasin en ligne
Dans cet exercice, nous nous familiarisons avec les manipulations de dictionnaires sur une thématique de magasin en ligne.
« Chez Geek and sons tout ce qui est inutile peut s’acheter, et tout ce qui peut s’acheter est un peu trop cher. »
La base de prix des produits de Geek and sons est représentée en Python par un dictionnaire avec :
- les noms de produits, de type
str, comme clés ; - les prix des produits, de type
float, comme valeurs associées.
Question 1
Donner une expression Python pour construire la base des prix des produits correspondant à la table suivante :
| Nom du produit | Prix TTC |
|---|---|
| Sabre Laser | 229.0 |
| Mitendo DX | 127.30 |
| Coussin Linux | 74.50 |
| Slip Goldorak | 29.90 |
| Station Nextpresso | 184.60 |
Question 2
Définir une fonction disponibilite qui, étant donné un nom de produit prod et une
base de prix prix, retourne True si le produit est présent dans la base, ou False
sinon.
Question 3
Définir une fonction prix_moyen qui, étant donné une base de prix (contenant au
moins un produit), retourne le prix moyen des produits disponibles.
Par exemple :
prix_moyen(
{
"Sabre Laser": 229.0,
"Mitendo DX": 127.30,
"Coussin Linux": 74.50,
"Slip Goldorak": 29.90,
"Station Nextpresso": 184.60,
}
)
129.06
Question 4
Définir une fonction fourchette_prix qui, étant donné un prix minimum mini, un
prix maximum maxi et une base de prix, retourne l’ensemble des noms de produits
disponibles dans cette fourchette de prix.
Par exemple :
fourchette_prix(
50.0, 200.0, {
'Sabre Laser': 229.0,
'Mitendo DX': 127.30,
'Coussin Linux': 74.50,
'Slip Goldorak': 29.90,
'Station Nextpresso': 184.60
})
{'Coussin Linux', 'Mitendo DX', 'Station Nextpresso'}
Question 5
Le panier est un concept omniprésent dans les sites marchands, Geeks and sons n’échappe pas à la règle. En Python, le panier du client sera représenté par un dictionnaire avec :
- les noms de produits comme clés ;
- une quantité d’achat comme valeurs associées.
Donner une expression Python correspondant à l’achat de trois sabres lasers, de deux coussins Linux et d’un slip Goldorak.
Question 6
Définir une fonction tous_disponibles qui, étant donné un panier d’achat panier et
une base de prix, retourne True si tous les produits demandés sont disponibles, ou
False sinon.
Question 7
Définir une fonction prix_achats qui, étant donné un panier d’achat panier et une
base de prix, retourne le prix total correspondant.
Par exemple :
prix_achats(
{"Sabre Laser": 3, "Coussin Linux": 2, "Slip Goldorak": 1},
{
"Sabre Laser": 229.0,
"Mitendo DX": 127.30,
"Coussin Linux": 74.50,
"Slip Goldorak": 29.90,
"Station Nextpresso": 184.60,
},
)
865.9
Remarque. On supposera que tous les articles du paniers sont disponibles dans la base de produits.
Correction
Dans cet exercice, nous nous familiarisons avec les manipulations de dictionnaires sur une thématique de magasin en ligne.
« Chez Geek and sons tout ce qui est inutile peut s’acheter, et tout ce qui peut s’acheter est un peu trop cher. »
La base de prix des produits de Geek and sons est représentée en Python par un dictionnaire avec :
- les noms de produits, de type
str, comme clés ; - les prix des produits, de type
float, comme valeurs associées.
Question 1. Donner une expression Python pour construire la base des prix des produits correspondant à la table suivante :
| Nom du produit | Prix TTC |
|---|---|
| Sabre laser | 229.0 |
| Mitendo DX | 127.30 |
| Coussin Linux | 74.50 |
| Slip Goldorak | 29.90 |
| Station Nextpresso | 184.60 |
ma_base_de_prix = {
"Sabre laser": 229.0,
"Mitendo DX": 127.30,
"Coussin Linux": 74.50,
"Slip Goldorak": 29.90,
"Station Nextpresso": 184.60,
}
Question 2.
Donner une définition de la fonction disponibilite qui, étant donné un nom de produit prod
et une base de prix prix, retourne True si le produit est présent dans la base, ou False sinon.
def disponibilite(prod, base_de_prix):
for cle in base_de_prix:
if cle == prod:
return True
return False
print(disponibilite("Slip Goldorak", ma_base_de_prix))
True
Question 3.
Donner une définition de la fonction prix_moyen qui, étant donné une base de prix (contenant
au moins un produit), retourne le prix moyen des produits disponibles.
Par exemple :
prix_moyen(
{
"Sabre Laser": 229.0,
"Mitendo DX": 127.30,
"Coussin Linux": 74.50,
"Slip Goldorak": 29.90,
"Station Nextpresso": 184.60,
}
)
129.06
def prix_moyen(base_de_prix):
somme = 0
for cle in base_de_prix:
somme += base_de_prix[cle]
moyenne = somme / len(base_de_prix)
return moyenne
print(prix_moyen(ma_base_de_prix))
129.06
Deuxième possibilité :
def prix_moyen(base_de_prix):
somme = 0
for valeur in base_de_prix.values():
somme += valeur
moyenne = somme / len(base_de_prix)
return moyenne
print(prix_moyen(ma_base_de_prix))
129.06
Question 4.
Donner une définition de la fonction fourchette_prix qui, étant donné un prix minimum
mini, un prix maximum maxi et une base de prix, retourne l’ensemble des noms de produits
disponibles dans cette fourchette de prix.
Par exemple :
fourchette_prix(
50.0, 200.0, {
'Sabre Laser': 229.0,
'Mitendo DX': 127.30,
'Coussin Linux': 74.50,
'Slip Goldorak': 29.90,
'Station Nextpresso': 184.60
})
{'Coussin Linux', 'Mitendo DX', 'Station Nextpresso'}
def fourchette_prix(mini, maxi, base_de_prix):
produits = []
for cle, valeur in base_de_prix.items():
if mini <= valeur <= maxi:
produits.append(cle)
return produits
print(fourchette_prix(50.0, 200.0, ma_base_de_prix))
['Mitendo DX', 'Coussin Linux', 'Station Nextpresso']
Question 5. Le panier est un concept omniprésent dans les sites marchands, Geeks and sons n’échappe pas à la règle. En Python, le panier du client sera représenté par un dictionnaire avec :
- les noms de produits comme clés ;
- une quantité d’achat comme valeurs associées.
Donner une expression Python correspondant à l’achat de trois sabres lasers, de deux coussins Linux et d’un slip Goldorak.
mon_panier = {"Sabre laser": 3, "Coussin Linux": 2, "Slip Goldorak": 1}
Question 6.
Donner une définition de la fonction tous_disponibles qui, étant donné un panier d’achat
panier et une base de prix, retourne True si tous les produits demandés sont disponibles, ou
False sinon.
def tous_disponibles(panier, base_de_prix):
for cle in panier:
if cle not in base_de_prix:
return False
return True
print(tous_disponibles(mon_panier, ma_base_de_prix))
True
Question 7.
Donner une définition de la fonction prix_achats qui, étant donné un panier d’achat panier
et une base de prix, retourne le prix total correspondant.
Par exemple :
prix_achats(
{"Sabre Laser": 3, "Coussin Linux": 2, "Slip Goldorak": 1},
{
"Sabre Laser": 229.0,
"Mitendo DX": 127.30,
"Coussin Linux": 74.50,
"Slip Goldorak": 29.90,
"Station Nextpresso": 184.60,
},
)
865.9
Remarque. On supposera que tous les articles du paniers sont disponibles dans la base de produits.
def prix_achats(panier, base_de_prix):
facture = 0
for article, nbre_article in panier.items():
facture += nbre_article * base_de_prix[article]
return facture
print(prix_achats(mon_panier, ma_base_de_prix))
865.9
Exercice 10 - Statistiques sur les lettres
Dans cet exercice, on effectue quelques calculs statistiques sur les fréquences de lettres dans des textes (chaînes de caractères).
Les fréquences (ou nombre d’occurrences) des lettres sont représentées sous la forme d’un dictionnaire avec :
- des lettres (caractères) comme clés ;
- des entiers naturels (fréquence du caractère) pour les valeurs associées.
Pour séparer les lettres de la langue française des autres caractères possibles dans les chaînes, on utilise la fonction suivante :
def est_lettre(c):
"""str -> bool
Hypothèse : len(c) == 1 (caractère)
Retourne True si le caractère c est une lettre, ou False sinon."""
return (
((c >= "a") and (c <= "z"))
or ((c >= "A") and (c <= "Z"))
or (c in {"é", "è", "à", "ù", "œ"})
)
Question 1
Définir une fonction frequences_lettres qui étant donnée un chaîne de caractère s
retourne les fréquences des lettres de s sous la forme d’un dictionnaire.
Par exemple :
frequences_lettres('alea jacta est')
{'a': 4, 'l': 1, 'e': 2, 'j': 1, 'c': 1, 't': 2, 's': 1}
frequences_lettres("l'élève")
{'é': 1, 'e': 1, 'v': 1, 'l': 2, 'è': 1}
Question 2
Définir une fonction lettre_freq_max qui retourne la lettre de fréquence maximale
dans un dictionnaire freqs de fréquences.
Par exemple :
lettre_freq_max(frequences_lettres('alea jacta est'))
'a'
lettre_freq_max(frequences_lettres("l'élève"))
'l'
Remarque : s’il y a plusieurs lettres de fréquence maximale, alors on n’en retourne qu’une choisie arbitrairement.
Question 3
Dans cette question, nous aimerions effectuer notre petit test statistique sur un véritable texte.
Pour cela, nous allons tout d’abord définir une fonction chargement_texte
permettant de lire un fichier texte et de placer le résultat dans une chaîne de
caractères.
Remarque. Nous n’étudions pas le chargement et la sauvegarde des fichiers dans ce cours, donc on utilisera cette fonction en suivant simplement sa spécification.
Pour les plus curieux, on pourra lire le cours
def chargement_texte(fichier):
"""str -> str
Hypothèse : le fichier est présent sur le disque
Retourne la chaîne de caractères correspondant au contenu
du fichier."""
# contenu : str
contenu = "" # contenu du fichier
with open(fichier, "r") as f:
contenu = f.read()
return contenu
On récupérera alors un fichier texte (encodage UTF-8) de langue française pour en étudier le contenu.
On peut par exemple récupérer un texte intégral via le Projet Gutenberg, à l’adresse suivante : http://www.gutenberg.org
Pour les exemples on a choisi Quatrevingt treize de Victor Hugo que l’on trouvera ici .
Donner deux expressions Python permettant de :
- récupérer le dictionnaire des fréquences des lettres présentes dans votre texte d’exemple ;
- trouver la lettre dont la fréquence est la plus grande.
Question 4
On souhaite maintenant connaître les lettres qui ne dépassent pas une fréquence
donnée dans un texte. Définir une fonction lettres_freq_inf qui étant donné un
dictionnaire de fréquences freqs et une fréquence fseuil retourne l’ensemble des
lettres de fréquence inférieure ou égale à fseuil.
Par exemple :
lettres_freq_inf(frequences_lettres('alea jacta est'), 1)
{'c', 'j', 'l', 's'}
lettres_freq_inf(frequences_lettres("l'élève"), 2)
{'e', 'l', 'v', 'è', 'é'}
Remarque. On fera l’hypothèse que la fréquence de seuil est strictement positive. En effet, nous n’étudions pas l’absence d’un lettre dans le texte.
Question 5
Donner une expression Python permettant d’obtenir l’ensemble des lettres utilisées moins de 100 fois dans votre texte.