Les dictionnaires.

Introduction.

Les dictionnaires (ou tableaux associatifs) ont déjà été abordé en première, il permettent de retrouver une données à partir d'une clef (et pas d'un index comme pour un tableau. Nous allons voir dans ce chapitre comment implémenter un dictionnaire et par là aborder la notion de table de Hachage.


			
Remarque

Dans les versions récentes de Python, si on demande à afficher le dictionnaire, les jours vont du lundi au dimanche (comme au moment de la création). Les nouvelles versions de python utilise des dictionnaires ordonnées, dans un dictionnaire basique l'ordre n'est pas garantie

Interface.

Les interfaces de base d'un tableau associatif sont :

Implémentation

Nous allons créer un tableau associatif qui marchera avec des clefs de type chaîne de caractères, le principe étant le même avec les autres type de clef. (il n'y a pas besoin d'avoir des types identiques pour les clefs dans un dictionnaire Python)

Le principe est relativement simple, on part d'un tableau indexé (le tableau est la structure de base) de taille fixe (généralement grand , puis à chaque clef on associe un index et on place le coupe (clef, indexe dans la tableau).

fonction de Hachage

Une fonction de hachage a pour but de transformer un objet quelconque (ici une chaîne de caractère) en un nombre (qui servira d'index). Les fonctions de hachages sont importantes et utilisées notamment en cryptographie, donnons des exemples de table de hachage.

  1. A une chaîne on associe sa longueur. f("bonjour") = 7.
  2. A une chaîne on associe la somme des représentation ASCII des caractères. g("bonjour") = 767
Longueur : Somme des caractères :
Remarque
Exercices
  1. Calculer f("Salut"), f("salut"), g("Salut"), g("salut"), f("dalut"), g("dalut"), un des critère d'une bonne fonction de hachage est de donner un résultat différent si une petite faute de frappe apparaît, les deux fonctions données en exemple vérifient-elles ce critère ?
  2. On considère la fonction de hachage \(h\) qui fait la somme des codes ASCII des lettres multipliées par 256place de la lettre dans le mot - 1. Par exemple $$h("abd") = 97×26^0 + 98×26^1 + 100×26^2 = 6 578 785$$.

    La programmer en python. La fonction python qui retourne le code unicode d'un caractere est ord.

Collisions

Prenons comme fonction de hachage la longueur d'un mot, notre dictionnaire est au départ un tableau indexé (de taille 10 pour se fixer les idées. Plaçons le couple clef = "lundi", valeur = "Monday", comme lundi a pour longueur 5 on va ranger le couple (comme un tuple ("lundi","Monday")) dans la case d'indice 5 du tableau. Plaçons maintenant le couple clef = "mardi", valeur = "Tuesday", comme mardi a aussi une longueur de 5 il faut le placer dans la case d'indice 5 mais il y a déjà un élément dans cette case ! On dit qu'il y a collision.

Pour éviter le plus possible les collisions on doit :

Malheureusement en mathématiques il existe un résultat en combinatoire appelé paradoxe des anniversaires qui montre que même avec une fonction de hachage qui garantie la répartition équitable et un tableau de taille 356 il suffit de rentrer 23 clefs pour avoir plus d'une chance sur deux d'avoir une collision. Les collisions sont donc plus ou moins inévitables et on a deux façons d'en tenir compte.

Exercices
  1. Donner deux chaînes qui ont la même image par la fonction f, de même pour la fonction g.
  2. Jean affirme : "Deux chaînes ont la même image par g si et seulement si elles sont des annagrammes". Jean a t'il raison ?
  3. La fonction de hachage h de l'exercice plus haut peut elle avoir des collisions ? Est elle bien répartie ?

Première façon.

On place le couple clef-valeur dans la case d'indice obtenue par la fonction de hachage et si elle est déjà occupée on passe à la case libre qui suit.

Indice :0123456789
clef :
valeur :

Deuxième façon.

On place le couple clef-valeur dans une liste elle même contenue dans la case d'indice obtenue dans la table de hachage.

Indice :0123456789

Implémentation.

Voici une des façons d'implémenter un dictionnaire en utilisant la deuxième façon, ici on surcharge les méthodes pour avoir la même utilisation qu'avec les dictionnaires de base de Python, on peut même itérer sur une instance de Dico !

On utilise un tableau self._tableau (de taille fixe mais comme Python n'a pas de "vrai" tableau on prend une liste), On utilise ensuite les listes de bases de python, mais généralement on utilise des listes chainées (voir cours précédent).


			
Remarque
Exercices

(Dur mais utile) Faire une implémentation d'un dictionnaire mais en suivant la première méthode.