Pour manipuler un ensemble de données, il est possible d’utiliser des tableaux
(cf type List). Cependant, cette approche montre ses limites lorsque les
informations à manipuler sont structurées et hétérogènes, comme pour décrire
une personne (nom, prénom, âge…) par exemple.
Problème sans dictionnaire
Pour gérer une liste de personnes, une solution connue consiste de créer un tableau par information ; exemple :
from typing import List
noms: List[str] = ["Tehei", "Tufari", "Li", "Müller"]
prenoms: List[str] = ["Hiria", "Manutea", "Wei", "Hans"]
for i in range(len(noms)):
nom_complet = prenoms[i] + " " + noms[i]
print("Personne " + str(i + 1) + " : " + nom_complet)
Cette méthode présente des inconvénients importants : si une personne est ajoutée au tableau des noms mais pas à celui des prénoms, les données ne sont plus synchronisées. De plus, l’ajout d’une caractéristique (l’âge par exemple) nécessiterait un troisième tableau…
Le problème est que les informations relatives à une seule entité sont réparties dans plusieurs variables.
Solution avec un dictionnaire
Les dictionnaires de Python (tableaux associatifs dans d’autres langages) sont des structures de données qui permettent de regrouper plusieurs caractéristiques (par exemple celles d’une personne : nom, prénom…) en une seule variable. Dans cet exemple, “nom” et “prenom” sont les clés qui permettent d’accéder aux différentes caractéristique :
from typing import Dict
personne1: Dict = {"nom": "Tehei", "prenom": "Hiria"}
print(personne1["prenom"] + " " + personne1["nom"])
Pour gérer plusieurs personnes, il suffit de créer un tableau de dictionnaires :
from typing import List, Dict
personnes: List[Dict] = [
{"nom": "Tehei", "prenom": "Hiria"},
{"nom": "Tufari", "prenom": "Manutea"},
{"nom": "Li", "prenom": "Wei"},
{"nom": "Müller", "prenom": "Hans"}
]
for i in range(len(personnes)):
personne = personnes[i]
nom_complet = personne["prenom"] + " " + personne["nom"]
#ou: nom_complet = personne[i]["prenom"] + " " + personne[i]["nom"]
print("Personne " + str(i + 1) + " : " + nom_complet)
Alors qu’un tableau (type List) représente une collection d’éléments
homogènes, un dictionnaire (type Dict) est un objet structuré — constitué
de plusieurs caractéristiques.
Le principal cas d’usage des dictionnaires est donc la gestion d’entités : un profil utilisateur, une fiche produit… La programmation orientée objet qui remplit également cet objectif sera vue ultérieurement.
Un dictionnaire permet de regrouper plusieurs caractéristiques d’une entité
sous la formes de paires (clé, valeur). La clé correspond à une caractéristique
(un champ / un attribut / une propriété). La syntaxe permettant de désigner
une caractéristique utilise des crochets : nom_var_dict["nom_clé"].
Ce cours se limite aux clés de type str.
Création et initialisation
La création d’un dictionnaire consiste à initialiser cette structure de données pour y stocker un enregistrement. Il existe deux manières principales de le faire.
La première est de créer un dictionnaire vide, puis de le compléter ensuite en affectant des valeurs à des clés ; exemple :
from typing import Dict
personne: Dict = {}
print("Dictionnaire vide : " + str(personne))
personne["nom"] = "Tehei"
personne["prenom"] = "Hiria"
print("Dictionnaire rempli : " + str(personne))
La seconde méthode consiste à initialiser le dictionnaire directement avec une ou plusieurs paires de clés / valeurs :
- les accolades
{}définissent le début et la fin du dictionnaire ; - les caractéristiques sont déclarées sous la forme
"nom_clé" : valeur; - les paires sont séparées par des virgules.
Exemple :
from typing import Dict
personne: Dict = {"nom": "Tehei", "prenom": "Hiria"}
print("Dictionnaire initialisé : " + str(personne))
Accès à une valeur
La valeur associée à une clé peut être affectée à une variable, utilisée dans une expression, passée en paramètre à une fonction… exemple :
from typing import Dict
personne: Dict = {"nom": "Tehei", "prenom": "Hiria"}
nom_personne: str = personne["nom"]
print("Nom de la personne : " + nom_personne)
print("Prénom de la personne : " + personne["prenom"])
Si la clé n’existe pas, une erreur KeyError est déclenchée. La méthode get
permet d’éviter ce problème et de renvoyer une valeur par défaut si une clé
n’existe pas : dictionnaire.get("clé", valeur_par_defaut) ; exemple :
personne: Dict = {"nom": "Tehei", "prenom": "Hiria"}
print(personne["courriel"]) #déclenche une erreur
civilite = personne.get("civilite", "M/Mme")
print(civilite)
personne["civilite"] = "Mme"
civilite = personne.get("civilite", "M/Mme")
print(civilite)
Modification d’un élément
Si la clé existe déjà dans le dictionnaire, sa valeur est remplacée ; exemple :
from typing import Dict
personne: Dict = {"nom": "Tehei", "prenom": "Hiria"}
print("Nom avant modification : " + personne["nom"])
personne["nom"] = "Tehei-Ura"
print("Nom après modification : " + personne["nom"])
Ajout d’un élément
Si la clé spécifiée n’existe pas, elle est créée ; exemple :
from typing import Dict
personne: Dict = {"nom": "Tehei", "prenom": "Hiria"}
print("Dictionnaire avant ajout : " + str(personne))
personne["age"] = 30
print("Dictionnaire après ajout : " + str(personne))
Remarque : la syntaxe pour l’ajout et la modification est identique ; l’opération effectuée dépend de la présence ou de l’absence de la clé dans le dictionnaire.
Suppression d’un élément
Pour supprimer une caractéristique / une paire (clé, valeur), on utilise l’instruction
del nom_var["nom_clé"] ; exemple :
from typing import Dict
personne: Dict = {"nom": "Tehei", "prenom": "Hiria", "age": 30}
print("Dictionnaire avant suppression : " + str(personne))
del personne["age"]
print("Dictionnaire après suppression : " + str(personne))
Le parcours d’un dictionnaire est une opération essentielle qui permet d’accéder à l’ensemble de ses données. Python propose plusieurs manières d’itérer de parcourir un dictionnaire.
Parcours des valeurs
Pour itérer uniquement sur les données contenues dans le dictionnaire, sans
se soucier de leurs clés, on utilise la méthode .values().
from typing import Dict
personne: Dict = {"nom": "Tehei", "prenom": "Hiria", "age": 30}
for valeur in personne.values():
print("- " + str(valeur))
Parcours des clés
Pour obtenir la liste des clés d’un dictionnaire, on utilise la méthode .keys() ;
la clé permet ensuite d’accéder à la valeur associée ; exemple :
from typing import Dict, Any #Any = n'importe quel type
personne: Dict = {"nom": "Tehei", "prenom": "Hiria", "age": 30}
for cle in personne.keys():
valeur: Any = personne[cle] #clé est une variable de type "str"
print("- " + cle + " : " + str(valeur))
Remarque : str(valeur) ne serait pas nécessaire pour des chaînes de caractères
(ici nom et prenom), mais est indispensable pour un nombre (ici age) ;
l’utiliser systématiquement (normalisation) ne pose pas de problème.
Parcours des paires (clé, valeur)
La méthode la plus complète et la plus courante est de parcourir le dictionnaire
en récupérant simultanément la clé et sa valeur associée. On utilise pour cela
la méthode .items() ; exemple :
from typing import Dict
personne: Dict = {"nom": "Tehei", "prenom": "Hiria", "age": 30}
for cle, valeur in personne.items():
print("- " + cle + ": " + str(valeur))
Remarque : la méthode items renvoie une liste (tableau) de tuples : la clé
et la valeur ; ce mécanisme est propre à Python. Pour l’expérimenter (approfondissement) :
from typing import Dict
personne: Dict = {"nom": "Tehei", "prenom": "Hiria", "age": 30}
print("Tableau des tuples : " + str(personne.items()))
items = list(personne.items()) #nécessaire pour accéder par indice
tuple = items[0]
print("Premier tuple clé / valeur : " + str(tuple))
key, value = items[0] #syntaxe particulière à Python
print("\nClé : " + key + "\nValeur : " + str(value))
key = tuple[0]
value = tuple[1]
print("\nClé : " + key + "\nValeur : " + str(value))
Test d’appartenance d’une clé
Pour vérifier de manière sécurisée si un attribut (une clé) existe dans un
enregistrement, on utilise l’opérateur in ; exemple :
from typing import Dict
from random import randint
personne: Dict = {"nom": "Tehei", "prenom": "Hiria", "age": 30}
if randint(0, 1) == 1: #une chance sur deux
personne["email"] = "hiria@tehei.pf"
if "email" in personne:
print("Email : " + personne["email"])
else:
print("La clé \"email\" n'existe pas.")
Vider un dictionnaire
La méthode .clear() permet d’effacer le contenu d’un dictionnaire ; exemple :
from typing import Dict
personne: Dict = {"nom": "Tehei", "prenom": "Hiria", "age": 30}
print("Dictionnaire avant clear : " + str(personne))
personne.clear()
print("\nDictionnaire après clear : " + str(personne))
Les dictionnaires sont souvent utilisés au sein de tableaux : List|Dict[…]],
pour gérer des collections d’entités, pour parcourir les enregistrements d’une
base de données ou d’un fichier CSV.
Exemple : l’application suivante gère une collection de personnes. Elle est constituée de deux fonctions et d’un programme principal.
Fonction de saisie
Cette fonction invite l’utilisateur à saisir les informations (nom, prénom, âge) de plusieurs personnes. La saisie se termine lorsque l’utilisateur entre un nom vide. La fonction retourne ensuite la collection complète des personnes saisies.
def saisir_personnes() -> List[Dict]:
"""
Saisit une liste de personnes et la retourne.
@return la collection de personnes
"""
personnes: List[Dict] = []
continuer: bool = True
while continuer:
nom: str = input("Nom (<Entrée> pour terminer) : ")
if nom == "":
continuer = False
else:
prenom: str = input("Prénom : ")
age: int = int(input("Âge : "))
p: Dict = {"nom": nom, "prenom": prenom, "age": age}
personnes.append(p)
return personnes
Fonction d’affichage
Cette fonction prend une collection de personnes en paramètre et affiche les attributs de chaque enregistrement.
def afficher_personnes(collection: List[Dict]) -> None:
"""
Affiche une liste de personnes de manière formatée.
@param collection liste des personnes
"""
for personne in collection:
for cle, valeur in personne.items():
print("- " + cle + ": " + str(valeur))
print("\n")
Programme principal
Le programme principal utilise les deux fonctions.
from typing import List, Dict
#fonctions saisir_personnes et afficher_personnes
if __name__ == "__main__":
liste_des_personnes: List[Dict] = saisir_personnes()
afficher_personnes(liste_des_personnes)