Skip to content

Les n-uplets et dictionnaires

Présentation

Jusqu'à maintenant, on a vu comment utiliser les listes Python permettant de stocker des séquences d'éléments (de même nature ou non).

Imaginons que nous souhaitions écrire un programme pour déterminer quel est le mois de l’annéele plus d’élèves du lycée sont nés. On suppose donnés, pour chaque élève, son nom, sous la forme d’une chaîne de caractères, et sa date de naissance, sous la forme de trois entiers. À l'aide des listes, on pourrait stocker ces informations de la manière suivante :

nom = [ "Alice", "Bob", "Charles", "Delphine", ... ]
jour = [ 7, 9, 14, 11, ... ]
mois = [ 1, 12, 12, 1, ... ]
annee = [ 1941, 1909, 1965, 1938, ... ]

Mais cette représentation n'est pas idéale. Si par exemple on souhaite trier les individus par année de naissance, on sera obligé de réorganiser les éléments dans les quatre listes, ce qui n'est pas le plus intuitif et le moins coûteux.

Une première manière de répondre à cette problématique est de créer une liste unique dans lequel chaque élément contiendra toutes les informations sur la personne.

On pourrait faire ceci en utilisant des listes de listes, ce qui donnerait :

individus = [["Alice", 7, 1, 1941], ["Bob", 9, 12, 1909], ["Charles", 14, 12, 1965], ["Delphine", 11, 1, 1938]]

Mais ce n'est pas l'idéal non plus car il est préférable qu'une liste Python contienne des éléments homogènes (c'est-à-dire de même type), ce qui n'est pas le cas ici.

Les dictionnaires

La représentation précédente n'est très pratique, car on doit retenir la nature de chaque information.

C'est pourquoi, une autre manière de représenter ces données est d'utiliser des n-uplets nommés, à l'aide d'une autre structure de données du langage Python appelé dictionnaire.

Un dictionnaire est une structure qui associe des valeurs à des clés. Ainsi, le dictionnaire

{"nom":"Alice", "jour":7, "mois":1, "annee":1941}

contient quatre clés, ici les chaînes de caractères "nom", "jour", "mois" et "année", auxquelles sont respectivement associées les valeurs "Alice", 7, 1 et 1941.

Si l'on souhaite représenter les données de individus dans un dictionnaire, on peut écrire :

individus = [{'nom': "Alice", 'jour': 7, 'mois': 1, 'annee': 1941},
            {'nom': "Bob", 'jour': 9, 'mois': 12, 'annee': 1909},
            {'nom': "Charles", 'jour': 14, 'mois': 12, 'annee': 1965},
            {'nom': "Delphine", 'jour': 11, 'mois': 1, 'annee': 1938}]

Contrairement à un tableau (représenté avec une liste en Python), les clés d’un dictionnaire ne sont pas limitées à un ensemble d’entiers de la forme 0, 1, . . . , n − 1.

Un dictionnaire peut être construit en donnant explicitement toutes ses entrées, comme c'est le cas pour le dictionnaire précédent représentant l’élève Alice.
On peut également en construire un à partir du dictionnaire vide, noté {}, en y ajoutant peu à peu des entrées avec des affectations de la forme d[clé] = valeur.

>>> d = {}
>>> d["Homer"] = "le mari de Marge"
>>> d["Marge"] = "la femme d’Homer"
>>> d["Lisa"] = "la fille de Marge et Homer"
>>> d
{'Homer': 'le mari de Marge', 'Marge': 'la femme d’Homer', 'Lisa': 'la fille de Marge et Homer'}
>>> len(d)
3
L'ordre d'insertion n'a pas d'importance, puisque contrairement à une liste ou à un tuple, les éléments d'un dictionnaire ne sont pas ordonnés, ils sont affichés dans un ordre arbitraire.

On peut accéder à la valeur associée à une clé avec la construction d[clé] et on peut tester si le dictionnaire possède une entrée pour une certaine clé avec la construction clé in d.

>>> d["Lisa"]
la fille de Marge et Homer
>>> "Lisa" in d
True
>>> "Bart" in d
False

Tester si un dictionnaire possède une clé donnée se fait de manière quasiment instantanée (en temps constant), ce qui est donc moins coûteux que de chercher un élément dans une liste, où la complexité est linéaire dans le pire des cas (puisqu'il faut parcourir chaque élément jusqu'à trouver le bon).

Sans rentrer dans les détails, cela s'explique parce que les dictionnaires, tout comme les ensembles en Python (une autre structure qui n'est pas au programme) sont, en interne, implémentés à l'aide d'une table de hachage, une structure de données très efficace pour la recherche et l'insertion d'éléments.

Si on tente d’obtenir la valeur associée à une clé qui n’est pas dans le dictionnaire, cela lève une erreur. Par exemple :

>>> d["Bart"]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
KeyError: Bart

Comme pour une liste, le contenu d’un dictionnaire peut être modifié après sa création, en remplaçant la valeur associée à une clé par une autre valeur, par exemple :

>>> d["Lisa"] = "modèle de La Joconde"
>>> len(d)
3
>>> d["Lisa"]
modèle de La Joconde

Il est également possible de supprimer une entrée du dictionnaire avec l’instruction del.

>>> del d["Lisa"]
>>> "Lisa" in d
False
>>> len(d)
2

Parcourir un dictionnaire

Le parcours des éléments d'un dictionnaire peut se faire de différentes façons.

Si l'on prend le dictionnaire suivant :

d = {"nom":"Alice", "jour":7, "mois":1, "annee":1941}

On peut parcourir les clés de la façon suivante :

###

d = {"nom":"Alice", "jour":7, "mois":1, "annee":1941}bksl-nlbksl-nlfor cle in d:bksl-nl print(cle)bksl-nl

On peut également parcourir les clés d'un dictionnaire avec la construction d.keys() :

###

d = {"nom":"Alice", "jour":7, "mois":1, "annee":1941}bksl-nlbksl-nl# Afficher chaque clé du dictionnairebksl-nlfor cle in d.keys():bksl-nl print(cle)bksl-nlbksl-nl# Créer une liste contenant chaque clé du dictionnairebksl-nlcles = list(d.keys())bksl-nlprint(cles)bksl-nl

Si l'on souhaite faire la même chose avec les valeurs associées aux clés du dictionnaire, le principe est le même mais avec la construction d.values() :

###

d = {"nom":"Alice", "jour":7, "mois":1, "annee":1941}bksl-nlbksl-nl# Afficher chaque clé du dictionnairebksl-nlfor val in d.values():bksl-nl print(val)bksl-nlbksl-nl# Créer une liste contenant chaque clé du dictionnairebksl-nlvaleurs = list(d.values())bksl-nlprint(valeurs)bksl-nl

On peut également parcourir à la fois les clés et les valeurs avec la construction d.items(). Dans ce cas là, chaque élément sera un tuple de type (clé, valeur) :

###

d = {"nom":"Alice", "jour":7, "mois":1, "annee":1941}bksl-nlbksl-nl# Afficher chaque clé du dictionnairebksl-nlfor cle, val in d.items():bksl-nl print(f'{cle} : {val}')bksl-nlbksl-nl# Autre possibilitébksl-nlfor el in d.items():bksl-nl print(el)bksl-nlbksl-nl# Créer une liste de tuples (clé, valeur)bksl-nlelements = list(d.items())bksl-nlprint(elements)bksl-nl

Dictionnaires par compréhension

Enfin, tout comme pour les listes, il est possible de construire un dictionnaire par compréhension, par exemple :

>>> { x*x : x for x in range(10) }
{0: 0, 1: 1, 4: 2, 16: 4, 9: 3}

Exercices - Tuples

Exercice 1

Écrire une fonction afficher(liste) qui prend en entrée une liste de tuples représentant des données sur des élèves, de la forme :

[("Bastien", "Dubois", 15), ("Stéphane", "Carlier", 16), ("Vincent", "Duboeuf", 15)]

Et qui effectue un affichage comme suit (en prenant l'exemple de la liste ci-dessus) :

Bastien Dubois - 15 ans
Stéphane Carlier - 16 ans
Vincent Duboeuf - 15 ans
Correction exercice 1

Il y a plusieurs solutions pour écrire cette fonction.
On peut faire un parcours en récupérant chaque tuple contenu dans la liste :

def afficher(liste):
    for infos in liste:
        print(f"{infos[0]} {infos[1]} - {infos[2]} ans")

On peut également récupérer directement chaque information des tuples (prénom, nom et âge) dans des variables différentes :

def afficher(liste):
    for prenom, nom, age in liste:
        print(f"{prenom} {nom} - {age} ans")

On a ici utilisé des f-strings pour gérer les affichages.

Pour des rappels concernant les différentes façons d'utiliser la fonction print, vous pouvez consulter cette page de cours.

Exercices - Dictionnaires

Notebooks

Voici un notebook Capytale d'introduction sur les dictionnaires :

Activité - Les dictionnaires en Python

D'autres exercices sur les dictionnaires et tuples :

D'autres exercices