Chapitre 12: Les dictionnaires

J’habite en Allemagne et l’idiome guttural de ce pays n’est pas ma langue maternelle. Par conséquent, lorsqu’un mot me manque, je consulte un dictionnaire. Je me rends directement à l’emplacement précis du mot français, par exemple Ambulance, et ce mot français est comme une clé qui me donne accès à la valeur correspondante dans la langue de Rammstein :

Ambulance : Krankenwagen

Figurez-vous qu’il existe exactement le même procédé en Python et c’est bien plus pratique qu’une liste. Les dictionnaires sont la solution idéale pour réaliser un test d’appartenance et en extraire une valeur.

dico
Ne jamais laver un dictionnaire à 60°!

Limitation des listes

Le problème des listes, c’est qu’il s’agit d’une séquence d’objets indicés, c’est-à dire que pour avoir accès à un élément précis, il faut connaitre son indice :

[code language= »python »]
mots_fr = ["Ambulance", "Hôpital","Infirmière"]
mots_allemands = ["Krankenwagen", "Krankenhaus","Krankenschwester"]
[/code]

Par exemple, je sais que l’indice d’Infirmière est le nombre entier 2. Je consulte la liste allemande. Que trouve-t-on à l’indice 2? Krankenschwester.

Pas très pratique tout ça! En plus, est-ce que je suis sûr que les traductions sont rangées dans le bon ordre. Est-ce que le mot allemand qui est à l’indice 1 (Krankenhaus) correspond bien au mot français au même indice (Hôpital)? Si ça se trouve, c’est tout dans le désordre!

Pour éviter ce genre de désagréments, on pourrait alors imaginer une liste de listes contenant des paires mot_allemand – mot_français:

[code language= »python »]dictionnaire = [["Ambulance", "Krankenwagen"], ["Hôpital", "Krankenhaus"],["Infirmière", "Krankenschwester"], [(…), (…)]][/code]

Et pour trouver la traduction, on pourrait utiliser ce code:

[code language= »python »]
dictionnaire =[["Ambulance", "Krankenwagen"], ["Hôpital", "Krankenhaus"],["Infirmière", "Krankenschwester"]]
for i, element in enumerate (dictionnaire):
if "Hôpital" in dictionnaire[i]:
print(dictionnaire[i][1])[/code]

Résultat: « Krankenhaus »

« Ça marche, Ordinosor! On l’a, notre dictionnaire français-allemand ».

Ne t’emballe pas, jeune fou! je te rappelle que les listes sont des séquences. Cela signifie que pour faire un test d’appartenance, elles sont parcourues de l’indice 0 jusqu’à l’indice de l’élément recherché. En clair, si tu cherches la traduction de zygomatique qui se trouve à la fin du dictionnaire, il va falloir que tu tournes toutes les pages une par une et que tu lises tous les mots un par un! Tu n’as pas le choix, ton dictionnaire est une liste.

Tu sais quoi? On va se donner rendez-vous en 2025. Tu m’apporteras ta traduction. Allez vas-y, tourne les pages!

Bon… en attendant, entrons dans le vif du sujet.

Définition et déclaration d’un dictionnaire

Définition

Un dictionnaire est un ensemble dont les éléments sont des paires clé-valeur . Au niveau syntaxique, un dictionnaire est contenu entre deux accolades. Les éléments sont séparés par des virgules tandis que les paires clé-valeur sont séparées par deux points. Voici ce que ça donne:

nom_du_dictionnaire = {clé : valeur, clé : valeur, clé : valeur, (…) : (…)}

Un dictionnaire est modifiable et les valeurs peuvent être n’importe quel objet (immuable ou modifiable, il n’y a aucune restriction) mais les clés doivent absolument être des objets immuables (string, nombre entier, nombre décimal, tuple). Si la clé est un tuple, celui-ci ne doit contenir que des éléments immuables. Par exemple, ce genre de clé ([0, 1], [2, 3]) qui est un tuple contenant des listes modifiables va lever une exception (erreur):

TypeError: unhashable type: ‘list’

Déclarer un dictionnaire

  • Pour déclarer un dictionnaire, on utilise des accolades :

[code language= »python »]
dictionnaire = {} # dictionnaire vide
[/code]

  • Je viens de créer un dictionnaire vide mais je peux très bien créer un dictionnaire et y placer des éléments dès sa déclaration :

[code language= »python »]
capitales = {"France":"Paris", "Allemagne" : "Berlin"}
[/code]

Dans cet exemple, « France » est une clé tandis que « Paris » est une valeur.

  • Il existe une autre méthode pour créer un dictionnaire. Elle consiste à créer une liste de tuples que l’on transforme en dictionnaire grâce au constructeur dict().

[code language= »python »]
liste_capitales = [("France","Paris"), ("Allemagne","Berlin")]
capitales = dict(liste_capitales)
print(capitales)
[/code]

Résultat : {‘Allemagne’: ‘Berlin’, ‘France’: ‘Paris’}

  • Il n’est pas possible de dupliquer une clé. Si on le fait, ce sera la dernière valeur entrée pour cette clé qui sera prise en compte.

[code language= »python »]
capitales = {"France":"Paris", "Allemagne" : "Berlin", "France" : "Marseille"}
print(capitales)
[/code]

Résultat: {‘Allemagne’: ‘Berlin’, ‘France’: ‘Marseille’}

Ajouter un élément (paire clé-valeur)

Si je veux rajouter un élément, c’est très simple, je créé une nouvelle paire clé-valeur. La clé  est contenue entre des crochets et la valeur se trouve à la droite du signe d’affectation. La syntaxe est donc la suivante :

nom_du_dico[clé] = valeur

[code language= »python »]
capitales[‘Islande’] = "Reykjavik"
print(capitales)
[/code]

Résultat : {‘Allemagne’: ‘Berlin’, ‘Islande’: ‘Reykjavik’, ‘France’: ‘Paris’}

Diantre! Les éléments ne sont plus dans le même ordre? Comment se fait-ce?

Ça n’a aucune espèce d’importance. L’ordre est aléatoire car un dictionnaire n’est pas une séquence, c’est une implémentation de tables de hachage. Pour retrouver une valeur, nous avons seulement besoin de connaître sa clé.

Accéder à une valeur

Voici comment on accède à une valeur:

[code language= »python »]
capitales = {‘Allemagne’: ‘Berlin’, ‘Islande’: ‘Reykjavik’, ‘France’: ‘Paris’}
result = capitales["Allemagne"] #Je stocke le résultat dans une variable.
print(result)
[/code]

Résultat : « Berlin »

C’est simple et instantané! Le programme n’a pas besoin de parcourir le dictionnaire du début à la fin. Grâce à la clé (« Allemagne »), Python est en mesure de se rendre directement à la « page » souhaitée pour trouver la valeur et renvoyer cette dernière. Que le dictionnaire contienne dix éléments ou cinq cent millions, la vitesse d’exécution sera de toute façon identique!

Et si j’utilise une clé qui n’est pas dans le dictionnaire, Python lève une exception (erreur):

[code language= »python »]
result = capitales["Syldavie"]
print(result)
[/code]

KeyError: ‘Syldavie’

La méthode get() comme test d’appartenance

Pour contourner cette exception et éviter d’avoir un message d’erreur qui stoppe le programme, il suffit d’utiliser la méthode get() en lui passant deux arguments : la clé et le résultat renvoyé au cas où la clé serait absente du dictionnaire. Reprenons le code précédent :

[code language= »python »]
result = capitales.get("Syldavie", "Non répertorié.")
print(result)
[/code]

Résultat : Non répertorié.

Tester l’appartenance avec l’instruction in

Il est possible de tester l’appartenance d’une clé à un dictionnaire grâce à la puissante instruction in.

[code language= »python »]
capitales = {"France":"Paris", "Allemagne" : "Berlin","Islande": "Reykjavik"}
if "Islande" in capitales:
print(capitales["Islande"])
[/code]

Résultat : Reykjavik

Je précise que l’instruction in ne teste que l’appartenance des clés et non pas l’appartenance des valeurs.

[code language= »python »]
capitales = {"France":"Paris", "Allemagne" : "Berlin","Islande": "Reykjavik"}
if "Reykjavik" in capitales:
print("Test d’appartenance réussi")
else:
print("Cette clé est absente du dictionnaire")
[/code]

Résultat: Cette clé est absente du dictionnaire

Mettre à jour une valeur

Si on souhaite mettre à jour une valeur, c’est fort simple. Voici comment on procède:

[code language= »python »]
capitales = {"France":"Paris", "Allemagne" : "Berlin","Islande": "Reykjavik"}
capitales["France"] = "Marseille"
print(capitales)
[/code]

Résultat: {‘France’: ‘Marseille’, ‘Allemagne’: ‘Berlin’, ‘Islande’: ‘Reykjavik’}

Utiliser un tuple comme clé

C’est tout à fait possible, à la condition que le tuple ne contienne que des objets immuables. Quant à la valeur, elle peut être constituée par n’importe quel objet donc une liste ne pose aucun problème.

Dès lors, on peut très bien imaginer un dictionnaire avec en guise de clés, des tuples contenant les noms de capitales et les noms de pays et en guise de valeurs, des listes contenant la latitude et la longitude.

[code language= »python »]
coords = {("Paris","France"):["48° 51′ N", "2° 21′ E"], ("Berlin","Allemagne"): ["52° 31′ N", "13° 24′ O"]}
result = coords[("Paris", "France")]
print(result)
[/code]

Résultat : [’48° 51′ N’, ‘2° 21′ E’]

code_dict
Visualisation du code avec Pythontutor

Supprimer un élément grâce à l’instruction del

Nous avons vu comment rajouter un élément dans un dictionnaire. C’est d’une simplicité enfantine. Pas besoin de faire appel à la méthode append().

Pour supprimer un élément, on utilise l’instruction del. En fait, on supprime la clé et par conséquent, la valeur qui lui est associée.

[code language= »python »]
capitales = {"France":"Paris", "Allemagne" : "Berlin","Islande": "Reykjavik"}
del capitales["Allemagne"]
print(capitales)
[/code]

Résultat : {‘France’: ‘Paris’, ‘Islande’: ‘Reykjavik’}

Supprimer tout le dictionnaire grâce à l’instruction del

Notez bien que l’instruction del permet également de supprimer tout le dictionnaire. Il suffit pour cela, de ne pas lui passer de clé entre crochets.

[code language= »python »]
capitales = {"France":"Paris", "Allemagne" : "Berlin","Islande": "Reykjavik"}
del capitales
print(capitales)
[/code]

NameError: name ‘capitales’ is not defined

Ce message d’erreur nous confirme que le dictionnaire n’existe plus.

Utiliser la fonction intégrée len()

On peut également utiliser la fonction intégrée len() pour connaître le nombre de paires clé-valeur contenues dans un dictionnaire.

[code language= »python »]
capitales = {"France":"Paris", "Allemagne" : "Berlin","Islande": "Reykjavik"}
print(len(capitales))
[/code]

Résultat: 3

Aperçu de quelques méthodes associées aux dictionnaires

  • dict.clear() supprime tous les éléments d’un dictionnaire. En clair, il le vide.

[code language= »python »]
capitales = {"France":"Paris", "Allemagne" : "Berlin","Islande": "Reykjavik"}
capitales.clear() # Vide le dictionnaire
print(capitales)
[/code]

Résultat: {}

  • dict.items() retourne toutes les paires clé-valeur sous la forme d’une liste de tuples

[code language= »python »]
capitales = {"France":"Paris", "Allemagne" : "Berlin","Islande": "Reykjavik"}
result = capitales.items()
print(result)
[/code]

Résultat: dict_items([(‘Islande’, ‘Reykjavik’), (‘France’, ‘Paris’), (‘Allemagne’, ‘Berlin’)])

  • dict.keys() retourne toutes les clés du dictionnaire sous la forme d’une liste

[code language= »python »]
capitales = {"France":"Paris", "Allemagne" : "Berlin","Islande": "Reykjavik"}
result = capitales.keys()
print(result)
[/code]

Résultat: dict_keys([‘Islande’, ‘Allemagne’, ‘France’])

  • dict.values() retourne toutes les valeur du dictionnaire sous la forme d’une liste

[code language= »python »]
capitales = {"France":"Paris", "Allemagne" : "Berlin","Islande": "Reykjavik"}
result = capitales.values()
print(result)
[/code]

Résultat: dict_values([‘Berlin’, ‘Reykjavik’, ‘Paris’])

Conclusion

Un dictionnaire est un ensemble non ordonné de paires clé-valeur. Chaque clé donne accès à la valeur qui lui est associée. Plus puissant qu’une liste, Un dictionnaire est idéal pour réaliser un test d’appartenance. En effet, comme il s’agit d’une implémentation de table de hachage et non pas d’une séquence, la vitesse d’exécution du test d’appartenance n’est pas liée au nombre d’éléments que le dictionnaire contient.

Il existe des compréhensions de dictionnaire qui feront l’objet d’un chapitre ultérieur.