Les dictionnaires

Numérique et sciences informatiques

donnees

Les dictionnaires

Un dictionnaire en python est une sorte de liste mais au lieu d'utiliser des index , on utilise des clés alphanumériques.

Les dictionnaires sont des collections non ordonnées d'objets, c'est-à-dire qu'il n'y a pas de notion d'ordre (i.e. pas d'indice). On accède aux valeurs d'un dictionnaire par des clés.

Comment créer un dictionnaire python?

Pour initialiser un dictionnaire , on utile la syntaxe suivante:

mon_garage = {}

ou

>>> mon_garage = dict()

Comment ajouter des valeurs dans un dictionnaire python?

Pour ajouter des valeurs à un dictionnaire il faut indiquer une clé ainsi qu'une valeur:

>>> mon_garage = {}
>>> mon_garage["Ferrari"] = 1
>>> mon_garage["Porche"] = 2
>>> mon_garage["Bentley"] = 1
>>> mon_garage
{'Ferrari': 1, 'Porche': 2, 'Bentley' : 1}

Vous pouvez utiliser des clés numériques comme dans la logique des listes .

Comment récupérer une valeur dans un dictionnaire python?

La méthode get vous permet de récupérer une valeur dans un dictionnaire et si la clé est introuvable, vous pouvez donner une valeur à retourner par défaut:

>>> mon_garage = {"Ferrari": 1, "Porche": 2, "Bentley": 1}
print(mon_garage.get("Ferrari"))
print(mon_garage.get("Citroën", "Voiture inconnue"))
>>> 1
>>> Voiture inconnue

Comment supprimer une entrée dans un dictionnaire python?

Il est possible de supprimer une entrée en indiquant sa clé, comme pour les listes:

	>>> del mon_garage["Bentley"]  # voiture cassée
>>> mon_garage
{"Ferrari": 1, "Porche": 2}
ou avec la méthode pop
>>> mon_garage.pop("Bentley")
>>> mon_garage
{"Ferrari": 1, "Porche": 2}

Comment récupérer les clés d'un dictionnaire python par une boucle ?

Les dictionnaires en Python utilisent une table de hashage pour stocker les clés.

Pour récupérer les clés on utilise la méthode keys .

>>> mon_garage = {"Ferrari":1, "Porche":2}
>>> for cle in mon_garage.keys():
...     print (cle)
... 
Ferrari
Porche

Comment récupérer les valeurs d'un dictionnaire python par une boucle ?

Pour cela on utilise la méthode values .

>>> mon_garage = {"Ferrari":1, "Porche":2}
>>> for valeur in mon_garage.values():
...     print (valeur)
... 
1
2

Comment récupérer les clés et les valeurs d'un dictionnaire python par une boucle ?

Pour récupérer les clés et les valeurs en même temps, on utilise la méthode items qui retourne un tuple .

>>> mon_garage = {"Ferrari":1,"Porche":2}
>>> for cle,valeur in mon_garage.items():
...     print (cle, valeur)
... 
Ferrari 1
Porche 2

Comment utiliser des tuples comme clé dans un dictionnaire python?

Une des forces de python est la combinaison tuple/dictionnaire qui fait des merveilles dans certains cas comme lors de l'utilisation de coordonnées.

>>> b = {}
>>> b[(3,2)]=12
>>> b[(4,5)]=13
>>> b
{(4, 5): 13, (3, 2): 12}

Comment créer une copie indépendante d'un dictionnaire python?

Comme pour toute variable, vous ne pouvez pas copier un dictionnaire en faisant dic1 = dic2 :

>>>mon_garage
{'Ferrari': 1, 'Porche': 2, 'Bentley' : 1}
>>>ton_garage = mon_garage
>>>mon_garage["Ferrari"] = 0
>>>ton_garage
{'Ferrari': 0, 'Porche': 2, 'Bentley' : 1}

Pour créer une copie indépendante vous pouvez utiliser la méthode copy :

>>>mon_garage
{'Ferrari': 1, 'Porche': 2, 'Bentley' : 1}
>>>ton_garage = mon_garage.copy
>>>mon_garage["Ferrari"] = 0
>>>ton_garage
{'Ferrari': 1, 'Porche': 2, 'Bentley' : 1}

Comment fusionner des dictionnaires python?

La méthode update permet de fusionner deux dictionaires .

>>> mon_garage1 = {'Ferrari': '1'}
>>> mon_garage2 = {'Porche': '2'}
>>> mon_garage1.update(mon_garage2)
>>> print(mon_garage1)
{'Ferrari': '1', 'Porche': '2'}



Entraînement 1:

Soit le dictionnaire :

>>> d = {'ville': 'le moule', 'departement': 'Guadeloupe', 'habitants': 30000}
  1. Corriger l'erreur dans habitants, la bonne valeur est 20000.
  2. Implémenter du code pour afficher la liste des clés du dictionnaire.
  3. Implémenter du code pour afficher la liste des valeurs du dictionnaire.
  4. Implémenter du code pour afficher la liste des paires clé/valeur du dictionnaire.
  5. Écrire la phrase "le moule a 20000 habitants" à l'aide du dictionnaire d.

Entraînement 2 :

Supposons que vous ayez une chaîne de caractères et que vous vouliez compter le nombre de fois où apparaît chaque lettre. A l'aide d'un dictionnaire, coder une fonction qui réalise cela.

Voir une solution

Entraînement 3 :

On donne un extrait des logins d’accès au réseau du lycée :

toto  to12
tata    ta12
titi    1234

1) Créer une variable de type dict qui contient les couples identifiant - mot_de_passe ci-dessus.

2) Implémenter la saisie du login avec deux variables : identifiant et mot_de_passe

Construire une variable booléenne qui donne True en cas d’identification

correcte, et False dans le cas contraire :

Entraînement 3 :

On donne un extrait des logins d’accès au réseau du lycée :

toto  to12
tata    ta12
titi    1234

1) Créer une variable de type dict qui contient les couples identifiant - mot de passe ci-dessus.

2) La saisie du login fournit deux variables identifiant et mot_de_passe : une pour l’identifiant et l’autre pour le mot de passe.

Construire une variable booléenne qui donne True en cas d’identification

correcte, et False dans le cas contraire :

Entraînement 4 :

Voici un exemple de données permettant de manipuler un livre de recettes de cuisine`a partir de la liste des ingrédients desrecettes :

Recette Ingrédients
Gâteau au chocolat chocolat, oeuf, farine, sucre, beurre
Gâteau au yaourt yaourt, oeuf, farine, sucre
Crêpes oeuf, farine, lait, bière
Quatre-quarts oeuf, farine, beurre, sucre
Kouign-amann farine, beurre, sucre

On va modéliser en Python un livre de recettes, par un dictionnaire de type dict(str : list(str))dans lequel :

  • les noms des recettes, de type str, comme clés,
  • l’ensemble des ingrédients, de type list(str), comme valeurs associées

  1. Construire un dictionnaire mes_recettes correspondant au tableau ci-dessus.
  2. Voir une solution

  3. Définir une fonction nb_ingredients(D, nom) qui à partir d’un dictionnaire de recettes D, défini comme décrit ci-dessus,renvoie le nombre d’ingrédients de la recette nommé nom.
  4. Définir une fonction recherche_recettes(D,i) renvoyant l’ensemble des recettes du dictionnaire D qui utilisent l’ingrédient i.
  5. Définir une fonction recherche_recettes_2(D,i1,i2)renvoyant l’ensemble des recettes du dictionnaire D qui utilisent les ingrédients i1 et i2.
  6. Définir une fonction recherche_recettes_multi(D,Li) renvoyant l’ensemble des recettes du dictionnaire D qui utilisent tous les ingrédients de la liste Li.
  7. Définir une fonction recherche_recettes_sans_multi(D,Li) renvoyant l’ensemble des recettes du dictionnaire D qui n’utilisent aucun des ingrédients de la liste Li.

Entraînement 5 : Gestion d’un HashSet avec gestion des conflits de hachage

À partir du code ci-dessous, vous allez compléter et modifier certaines parties afin de manipuler les tables de hachage et de comprendre leur fonctionnement. Le code initial consiste à stocker des chaînes de caractères dans un tableau de hachage (HashSet) en utilisant une fonction de hachage simple.

# Tableau qui servira de squelette pour le HashSet
hashSet = []

# Initialisation du HashSet: Tableau de tableau de taille 2000
for i in range(2000):
    hashSet.append([])

def keyToInt(key):
    '''
    Fonction de hashage:
        Objectif: conversion du texte en valeur numérique pour trouver le bon sous-tableau dans HashSet
        Paramètre: key -> clé à ajouter/chercher dans HashSet
        Fonctionnement: Somme des caractères convertis en code ASCII avec ord moins 96 (ainsi 'a' = 1)
    '''
    val = 0
    for char in key:
        val += ord(char) - 96
    return val % 2000

def isHere(key, hashSet):
    '''
    Fonction de recherche
        Objectif: vérifie si la clé <key> se trouve dans la table de hachage <hashSet>
    '''
    index = keyToInt(key)
    return key in hashSet[index]

def addHash(key, hashSet):
    '''
    Fonction d'ajout
        Objectif: ajouter la clé <key> dans le tableau de hachage <hashSet> si elle n'est pas présente
    '''
    index = keyToInt(key)
    if key not in hashSet[index]:
        hashSet[index].append(key)

# Code de test
addHash("salut", hashSet)
print(isHere("salut", hashSet))

Questions

  1. Compréhension de la fonction de hachage
    Expliquez ce que fait la fonction keyToInt et pourquoi elle utilise ord(char) - 96 pour chaque caractère de la clé. Voir une solution
  2. Modification de la taille de la table de hachage
    Modifiez la taille de hashSet à 5000 au lieu de 2000. Que pensez-vous que cela changera dans les performances de l’algorithme ? Testez votre hypothèse avec le code. Voir une solution
  3. Gestion des conflits de hachage
    Imaginez qu’on veuille ajouter la clé "hello" et la clé "world" mais que les deux clés aient le même index avec la fonction de hachage actuelle.
    • Expliquez ce qui se passe actuellement dans ce cas.
    • Codez une fonction countCollisions(hashSet) qui retourne le nombre de collisions dans le HashSet (i.e., le nombre de sous-tableaux ayant plus d’un élément). Voir une solution
  4. Insertion et recherche dans le HashSet
    Expliquez le fonctionnement de addHash et isHere. Quelles sont les limites de ce HashSet ? Voir une solution
  5. Amélioration de la fonction de hachage
    La fonction de hachage actuelle est très simple. Modifiez la fonction keyToInt pour la rendre plus efficace. Par exemple, utilisez un poids croissant pour chaque caractère de la clé (i.e., le premier caractère n’a pas le même poids que le dernier). Voir une solution
    • Comparez les résultats en termes de collisions avec countCollisions.

Savoir faire

  • Savoir rechercher un élément dans un dictionnaire
  • Construire une entrée de dictionnaire

Fiche de cours