| |
| python:bases:dictionnaires [2021/05/25 16:39] – [Quiz] phil | python:bases:dictionnaires [2025/06/19 19:29] (Version actuelle) – modification externe 127.0.0.1 |
|---|
| | [[python:bases:ensembles|{{ :suivant.png?nolink&30|Ensembles}}]] |
| | [[:python:bases:tuples|{{ :retour.png?nolink&30|Tuples}}]] |
| | [[:python:accueilpython|{{ :iconemaison.jpg?nolink&30|Sommaire Python et microPython}}]] |
| |
| | ===== Python - Dictionnaires ===== |
| | |
| | [Mise à jour le : 16/8/2022] |
| | |
| | * **Sources** |
| | * **Documentation** sur Python.org : <html><a href="https://docs.python.org/fr/3.6/reference/index.html" target="_blank">référence du langage</a>, <html><a href="https://docs.python.org/fr/3/tutorial/datastructures.html#dictionaries" target="_blank">dictionnaire</a></html>, <html><a href="https://docs.python.org/fr/3.5/library/functions.html" target="_blank">fonctions natives</a></html> (built-in) |
| | |
| | * **Lectures connexes** |
| | * **Real Python** |
| | * <html><a href="https://realpython.com/python-ordereddict/" target="_blank">OrderedDict vs dict in Python: The Right Tool for the Job</a></html> |
| | * <html><a href="https://realpython.com/sort-python-dictionary/" target="_blank">Sorting a Python Dictionary: Values, Keys, and More</a></html> |
| | |
| | * ** Mots-clés** : dictionnaire, parcours de dictionnaires. |
| | |
| | <callout type="warning" icon="true">Les mots ci-dessous sont dits "réservés". Ils ne peuvent pas être utilisés comme nom de variable. Les mots __soulignés__ sont une nouveauté de Python 3. Les mots en **gras** sont utilisés dans cette page.</callout> |
| | |
| | | and | continue | finally | **is** | raise | |
| | | as | def | **for** | lambda | return | |
| | | assert | **del** | from | __None__ | __True__ | |
| | | __async__ | elif | global | __nonlocal__ | try | |
| | | __await__ | else | if | not | **while** | |
| | | break | except | import | or | with | |
| | | class | __False__ | **in** | pass | yield | |
| | |
| | |
| | * <html><a href="https://docs.python.org/fr/3.5/library/functions.html" target="_blank">Fonctions natives</a></html>** (built-in)**((Fonctions toujours disponibles.)) utilisées dans les exemples : **dict**()((**Constructeur** : un constructeur est, en programmation orientée objet, une fonction particulière appelée lors de l'instanciation. Elle permet d'allouer la mémoire nécessaire à l'objet et d'initialiser ses attributs.)), **del**(), **print**(), **range**(), **zip**(). |
| | |
| | ---- |
| | |
| | ==== 1. Introduction ==== |
| | Le dictionnaire est une implémentation de table de hash. Il permet l'accès, l'insertion et le test d'appartenance indépendamment du nombre d'éléments. Le dictionnaire est un objet conteneur. À la différence des séquences, qui sont indexées par des nombres, les dictionnaires sont indexés par des **clés**, qui peuvent être de n'importe quel type immuable ; les chaînes de caractères et les nombres peuvent toujours être des clés. |
| | |
| | <callout type="primary" icon="true">Les **dictionnaires** sont des objets **mutables**. Leur structure n'est pas ordonnée (ceci est dû à l'action de la fonction de hachage).Les **clés** doivent avoir un **type immuable**.</callout> |
| | |
| | ==== 2. Création ==== |
| | <callout type="primary" icon="true">On utilise l'expression suivante : //nom_dictionnaire// = **dict()** ou //nom_dictionnaire// = **{}** pour créer des dictionnaires vides.</callout> |
| | |
| | //Exemples// |
| | |
| | <code python *.py> |
| | # Première méthode |
| | dico = {} # dictionnaire vide |
| | dico = {'nom':'Martin','prenom':'Pierre-Emile'} # création en extension |
| | print(dico) # Résultat : {'nom': 'Martin', 'prenom': 'Pierre-Emile'} |
| | |
| | # Deuxième méthode |
| | dico = dict() # dictionnaire vide |
| | # La fonction native dict() construit un dictionnaire directement à partir d'une liste |
| | # de paires clé-valeur stockées sous la forme de tuples. |
| | dico = dict([('nom','Martin'),('prenom','Pierre-Emile')]) |
| | print(dico) # Résultat : {'nom': 'Martin', 'prenom': 'Pierre-Emile'} |
| | # ou |
| | # Construction à partir d'une liste de tuples et de la fonction native dict() |
| | l = [('nom','Martin'),('prenom','Pierre-Emile')] |
| | dico = dict(l) |
| | print(dico) # Résultat : {'nom': 'Martin', 'prenom': 'Pierre-Emile'} |
| | |
| | # Troisième méthode |
| | dico = dict(nom='Martin',prenom='Pierre-Emile') |
| | print(dico) # Résultat : {'nom': 'Martin', 'prenom': 'Pierre-Emile'} |
| | </code> |
| | |
| | <callout type="primary" icon="true">Les **accolades** délimitent les **dictionnaires**.</callout> |
| | |
| | ==== 3. Lecture de la valeur d'un élément ==== |
| | On accède à une valeur à partir de sa **clé** par //nom_dictionnaire//**[****//clé//****]**. Si la clé n'existe pas, une exception de type **KeyError** sera levée. |
| | |
| | //Exemple// |
| | |
| | <code python *.py> |
| | # En faisant un test d'appartenance on évite la génération d'une erreur KeyError si la clé est absente |
| | if 'nom' in dico: |
| | print(dico["nom"]) # résultat : Martin |
| | </code> |
| | |
| | ==== 4. Ajout ou modification d'un élément ==== |
| | <callout type="primary" icon="true">Le dictionnaire est un type **mutable**, et donc on peut **modifier la valeur** associée à une clé. On utilise l'expression suivante : //nom_dictionnaire//**[****//clé//****]** = //**valeur**//. Et de la même jaçon, **ajouter une entrée**.</callout> |
| | |
| | //Exemples// |
| | |
| | <code python *.py> |
| | dico = {} |
| | # La clé peut être une chaîne de caractères |
| | dico['nom']='Martin' |
| | dico['prenom']='Pierre-Emile' |
| | print(dico) #résultat : {'nom': 'Martin', 'prenom': 'Pierre-Emile'} |
| | |
| | # La clé peut être un tuple |
| | echiquier = {} |
| | echiquier[('a',1)] = 'tour blanche' |
| | print(echiquier) # résultat : {('a', 1): 'tour blanche'} |
| | </code> |
| | |
| | ==== 5. Suppression d'éléments ==== |
| | <callout type="primary" icon="true">On utilise **del**(//nom_dictionnaire//**[****//clé//****]**) ou //nom_dictionnaire//.**pop**("**clé**"). pop renvoie la valeur.</callout> |
| | |
| | <code python *.py> |
| | placard = {"chemise":6,"pantalon":4} |
| | del(placard["chemise"]) |
| | print(placard) # Résultat : {'pantalon': 4} |
| | n = placard.pop("pantalon") |
| | print(placard) # Résultat : {} |
| | print(n,"pantalon(s) donné(s)") # Résultat : 4 pantalon(s) donné(s) |
| | </code> |
| | |
| | ==== 6. Le parcours de dictionnaires ==== |
| | La méthode la plus fréquente pour parcourir tout un dictionnaire est à base de la méthode items. |
| | |
| | === 6.1 Parcours des clés et valeurs simultanément === |
| | <callout type="primary" icon="true">On utilise la méthode **items** de la classe **dict**. Elle renvoie une **liste**, contenant les couples **clé : valeur**, sous la forme d'un tuple.</callout> |
| | |
| | <code python *.py> |
| | placard = {"chemise": 6, "pantalon": 4, "chaussette": 10, "pull": 4} |
| | # A chaque tour de boucle, items renvoie un tuple constitué de la clé et de la valeur |
| | for cle, valeur in placard.items(): # notation de tuple unpacking |
| | print(cle, valeur) |
| | |
| | # Résultat |
| | chemise 6 |
| | pantalon 4 |
| | chaussette 10 |
| | pull 4 |
| | </code> |
| | |
| | On peut obtenir séparément la liste des clés et des valeurs. |
| | |
| | === 6.2 Parcours des clés === |
| | <callout type="primary" icon="true">On utilise la méthode **keys**() de la classe **dict**.</callout> |
| | |
| | <code python *.py> |
| | placard = {"chemise": 6, "pantalon": 4, "chaussette": 10, "pull": 4} |
| | for cle in placard.keys(): |
| | print(cle) |
| | |
| | # Résultat |
| | chemise |
| | pantalon |
| | chaussette |
| | pull |
| | </code> |
| | |
| | <callout type="primary" icon="true">L'itérateur sur les dictionnaires itère directement sur les clés.</callout> |
| | |
| | //Exemple// |
| | <code python *.py> |
| | # Dans l'exemple précédent, on obtient le même résultat san préciser la méthode keys() |
| | placard = {"chemise": 6, "pantalon": 4, "chaussette": 10, "pull": 4} |
| | for cle in placard: |
| | print(cle) |
| | |
| | # Résultat |
| | chemise |
| | pantalon |
| | chaussette |
| | pull |
| | </code> |
| | |
| | === 6.3 Parcours des valeurs === |
| | <callout type="primary" icon="true">On utilise la méthode **values**() de la classe **dict**.</callout> |
| | |
| | <code python *.py> |
| | placard = {"chemise": 6, "pantalon": 4, "chaussette": 10, "pull": 4} |
| | for valeur in placard.values(): |
| | print(valeur) |
| | |
| | # Résultat |
| | 6 |
| | 4 |
| | 10 |
| | 4 |
| | </code> |
| | |
| | <callout type="tip" icon="true">Les méthodes **keys**(), **values**() et **items**() retournent un objet particulier appelé : **une vue** (itérable et possédant le test d'appartenance). La caractéristique principale d'une vue est qu'elle est **mise à jour** en même temps que le dictionnaire.</callout> |
| | |
| | // Exemple // |
| | |
| | <code python *.py> |
| | # Création du dictionnaire en extension |
| | placard = {"chemise": 6, "pantalon": 4, "chaussette": 10, "pull": 4} |
| | k = placard.keys() # Création d'une "vue" sur le dictionnaire placard |
| | print(k) # Résultat : dict_keys(['chemise', 'pantalon', 'chaussette', 'pull']) |
| | placard['short'] = 3 # Ajout d'un couple dans le dictionnaire placard |
| | print(placard) # Résultat : {'chemise': 6, 'pantalon': 4, 'chaussette': 10, 'pull': 4, 'short': 3} |
| | # La vue a été modifiée sans réaffectation |
| | print(k) # Résultat : dict_keys(['chemise', 'pantalon', 'chaussette', 'pull', 'short']) |
| | |
| | # Test d'appartenance sur une vue |
| | 'chemise' in k # Résultat : True |
| | 'ceinture in k # Résultat : False |
| | </code> |
| | ==== 7. Formation d'un dictionnaire à partir de deux listes ==== |
| | <callout type="primary" icon="true">On utilise l'expression suivante : //nom_dictionnaire// = **dict**(**zip**(//listeClés//,//listeVal//))</callout> |
| | |
| | //Exemples// |
| | |
| | <code python *.py> |
| | # Formation du dictionnaire dico à partir de deux listes |
| | cles=['a','b','c'] |
| | valeurs=[1,2,3] |
| | dico=dict(zip(cles,valeurs)) |
| | |
| | # Affichage |
| | print(dico) # résultat : {'a': 1, 'b': 2, 'c': 3} |
| | </code> |
| | |
| | ==== 8. Transformation d'un dictionnaire en paramètres nommés d'une fonction ==== |
| | |
| | //Exemple// |
| | |
| | <code python *.py> |
| | parametres = {"sep" : " >> ", "end" : " -\n"} |
| | print("Voici", "un", "exemple", "d'appel", **parametres) |
| | # Résultat : Voici >> un >> exemple >> d'appel - |
| | </code> |
| | |
| | ==== 9. Gérer des enregistrements ==== |
| | Un enregistrement est une donnée composite qui contient plusieurs champs (struct ou un record dans d'autres langages). |
| | |
| | === 9.1 Implémenter un enregistrement comme un dictionnaire === |
| | |
| | //Exemple// |
| | |
| | <code python *.py> |
| | # Enregistrement |
| | personnes = [ |
| | {'nom': 'Pierre', 'age': 25, 'email': 'pierre@example.com'}, |
| | {'nom': 'Paul', 'age': 18, 'email': 'paul@example.com'}, |
| | {'nom': 'Jacques', 'age': 52, 'email': 'jacques@example.com'}, |
| | ] |
| | # Pour l'anniversaire de Pierre on fera : |
| | personnes[0]['age'] += 1 |
| | # Affichage |
| | for personne in personnes: |
| | print(10*"=") |
| | for info, valeur in personne.items(): |
| | print(f"{info} -> {valeur}") |
| | # Résultat |
| | # ========== |
| | # nom -> Pierre |
| | # age -> 26 |
| | # email -> pierre@example.com |
| | # ========== |
| | # nom -> Paul |
| | # age -> 18 |
| | # email -> paul@example.com |
| | # ========== |
| | # nom -> Jacques |
| | # age -> 52 |
| | # email -> jacques@example.com |
| | </code> |
| | |
| | <callout type="warning" icon="true">Problème : l'accès à un enregistrement suppose ici que l'on connaisse sa position. |
| | </callout> |
| | |
| | ===9.2 Un dictionnaire pour indexer les enregistrements === |
| | <callout type="tip" icon="true">Pour modéliser ces informations, il est plus adapté d'utiliser, non pas une liste, mais un **dictionnaire de dictionnaires**.</callout> |
| | |
| | //Exemple// |
| | <code python *.py> |
| | personnes = [ |
| | {'nom': 'Pierre', 'age': 25, 'email': 'pierre@example.com'}, |
| | {'nom': 'Paul', 'age': 18, 'email': 'paul@example.com'}, |
| | {'nom': 'Jacques', 'age': 52, 'email': 'jacques@example.com'}, |
| | ] |
| | # on crée un index permettant de retrouver rapidement une personne dans la liste |
| | index_par_nom = {personne['nom']: personne for personne in personnes} |
| | index_par_nom # Résultat : {'Pierre': {'nom': 'Pierre', 'age': 26, 'email': 'pierre@example.com'}, |
| | # 'Paul': {'nom': 'Paul', 'age': 18, 'email': 'paul@example.com'}, |
| | # 'Jacques': {'nom': 'Jacques', 'age': 52, 'email': 'jacques@example.com'}} |
| | # On accède à l'age de Pierre par |
| | index_par_nom['Pierre']['age'] # Résultat : 26 |
| | # au lieu de personnes[0]['age'], ce qui est plus pertinent car un dictionnaire n'est pas ordonné |
| | </code> |
| | ==== 9. Les méthodes de la classe dict ==== |
| | * **Source** <html><a href="https://www.w3schools.com/python/python_ref_dictionary.asp" target="_blank">w3schools.com</a></html> |
| | |
| | ^ Fonction ^ Paramètres ^ Effet ^ Structure ^ |
| | |**clear**() | |Supprime tous les éléments du dictionnaire. | //d//.**clear**() | |
| | |**copy**() | |Renvoie une copie du dictionnaire. | //d//.**copy**() | |
| | |**fromkeys**() | clés,valeur |Crée un dictionnaire à partir d'une liste de clés prenant la **même valeur** ou **None**. | //d//.**fromkeys**(//keys//,//value//)| |
| | |**get**() | clé,defaut |Renvoie la valeur de l'élément avec la clé spécifiée ou la valeur par défaut si celle-ci est absente. | //d//.**get**(//clé//, //defaut//) | |
| | |**items**() | |Renvoie les paires clé-valeur du dictionnaire. | //d//.**items**() | |
| | |**keys**() | |Renvoie la liste des clés du dictionnaire. | //d//.**keys**() | |
| | |**popitem**() | |Renvoie et supprime le dernier élément du dictionnaire. | //d//.**popitem**() | |
| | |**pop**() | clé |Renvoie et supprime l'élément correspondant à la clé. | //d//.**pop**(//clé//) | |
| | |**setdefault**()| clé,valeur |Renvoie l'élément correspondant à la clé. S'il n'est pas présent, insère la clé avec la valeur dans le dictionnaire. |//d//.**setdefault**(//clé//,//valeur//) | |
| | |**update**() | iterable |Met à jour le dictionnaire. | //d//.**update**(iterable)| |
| | |**values**() | |Renvoie les valeurs du dictionnaire . | //d//.**values**() | |
| | |
| | ---- |
| | |
| | ==== Résumé ==== |
| | * Un dictionnaire est un objet conteneur associant des clés à des valeurs. |
| | * Pour créer un dictionnaire en extension, on utilise la syntaxe **dictionnaire = {clé1:valeur1,clé2:valeur2,clén:valeurn}**. |
| | * On ajoute ou on remplace un élément dans un dictionnaire par **dictionnaire[clé] = valeur**. |
| | * On supprime une clé et sa valeur avec le mot-clé **del** ou la méthode **pop**. |
| | * On parcourt un dictionnaire avec les méthodes **keys**(), **values**() et **items**(). |
| | * On capture les paramètres nommés passés à une fonction avec la syntaxe **def** //nom_fonction//(**//parametres_nommes// : (les paramètres nommés se trouvent dans le dictionnaire //parametres_nommes//). |
| | |
| | {{ :python:bases:realpython.png?nolink|}} |
| | ==== Quiz ==== |
| | * <html><a href="https://realpython.com/quizzes/python-dicts/" target="_blank">Python Dictionaries Quiz</a></html> |
| | * <html><a href="https://realpython.com/quizzes/python-dictionary-iteration/" target="_blank">Python Dictionary Iteration Quiz</a></html> |