# Programmation Python/Dictionnaires
## Partie 1 - Introduction

* Avant-propos à l'attention des non-programmeurs
* Introduction
* Installation
* Éditeurs
* Programmer en deux minutes
** une messagerie instantanée
** un programme interfacé avec Wikipédia
** un serveur Web

## Partie 2 - Le langage

* Afficher un texte
* Structure d'un programme
* Variables
* Opérateurs
* Structures de contrôle
* Instructions répétitives
* Types
** Numériques
** Booléens
** Chaines de caractères
** Listes
** Tuples
** Dictionnaires
** Dates
** Ensembles
* Fonctions
* Modules
* Exercices
** Palindrome
* Regex
* Programmation orientée objet pour les non-programmeurs
* Classes
* Classes et Interfaces graphiques
* Fichiers
* Exceptions
* Bases de données
** Gestion
* L'interface CGI
* Applications web
* Réseau
* Threads

## Partie 3 - Les bibliothèques

* Bibliothèques pour Python
* L'interface graphique
* Utilisation de fenêtres et de graphismes
** Tkinter
** Widgets
** Turtle
* Les threads
* XML
* JSON
* Tests
* Analyse statique de programmes
* Fabric
* Le Web
** Django
** Karrigell
** Aiohttp

## Partie 1 - Introduction

* Avant-propos à l'attention des non-programmeurs
* Introduction
* Installation
* Éditeurs
* Programmer en deux minutes
** une messagerie instantanée
** un programme interfacé avec Wikipédia
** un serveur Web

## Partie 2 - Le langage

* Afficher un texte
* Structure d'un programme
* Variables
* Opérateurs
* Structures de contrôle
* Instructions répétitives
* Types
** Numériques
** Booléens
** Chaines de caractères
** Listes
** Tuples
** Dictionnaires
** Dates
** Ensembles
* Fonctions
* Modules
* Exercices
** Palindrome
* Regex
* Programmation orientée objet pour les non-programmeurs
* Classes
* Classes et Interfaces graphiques
* Fichiers
* Exceptions
* Bases de données
** Gestion
* L'interface CGI
* Applications web
* Réseau
* Threads

## Partie 3 - Les bibliothèques

* Bibliothèques pour Python
* L'interface graphique
* Utilisation de fenêtres et de graphismes
** Tkinter
** Widgets
** Turtle
* Les threads
* XML
* JSON
* Tests
* Analyse statique de programmes
* Fabric
* Le Web
** Django
** Karrigell
** Aiohttp
[ Modifier le sommaire ]

## Déclarations

Le dictionnaire ou tableau associatif n'est pas une séquence mais un autre type composite. Ils ressemblent aux listes dans une certaine mesure (ils sont modifiables comme elles), mais les éléments que nous allons y enregistrer ne seront pas disposés dans un ordre immuable. En revanche, nous pourrons accéder à n'importe lequel d'entre eux à l'aide d'un index spécifique que l'on appellera une clé, laquelle pourra être alphabétique, numérique, ou même d'un type composite sous certaines conditions.

## Création d'un dictionnaire

À titre d'exemple, nous allons créer un dictionnaire de langue, pour la traduction de termes informatiques anglais en français. Dans ce dictionnaire, les index seront des chaînes de caractères.
Puisque le type dictionnaire est un type modifiable, nous pouvons commencer par créer un dictionnaire vide, puis le remplir petit à petit. Du point de vue syntaxique, on reconnaît une structure de données de type dictionnaire au fait que ses éléments sont enfermés dans une paire d'accolades. Un dictionnaire vide sera donc noté { } :
Comme vous pouvez l'observer dans la ligne ci-dessus, un dictionnaire apparaît comme une série d'éléments séparés par des virgules (le tout étant enfermé entre deux accolades}. Chacun de ces éléments est constitué d'une paire d'objets : un index et une valeur, séparés par un double point.
Dans un dictionnaire, les index s'appellent des clés, et les éléments peuvent donc s'appeler des paires clé-valeur. Vous pouvez constater que l'ordre dans lequel les éléments apparaissent à la dernière ligne ne correspond pas à celui dans lequel nous les avons fournis. Cela n'a strictement aucune importance : nous n'essaierons jamais d'extraire une valeur d'un dictionnaire à l'aide d'un index numérique. Au lieu de cela, nous utiliserons les clés :
Contrairement à ce qui se passe avec les listes, il n'est pas nécessaire de faire appel à une méthode particulière pour ajouter de nouveaux éléments à un dictionnaire : il suffit de créer une nouvelle paire clé-valeur.

## Opérations sur les dictionnaires

Pour en enlever, vous utiliserez l'instruction del. Créons pour l'exemple un autre dictionnaire, destiné cette fois à contenir l'inventaire d'un stock de fruits. Les index (ou clés) seront les noms des fruits, et les valeurs seront les masses de ces fruits répertoriées dans le stock (il s'agit donc cette fois de valeurs de type numérique).
Si le patron décide de liquider toutes les pommes et de ne plus en vendre, nous pouvons enlever cette entrée dans le dictionnaire :
La fonction len est utilisable avec un dictionnaire : elle en renvoie le nombre d'éléments.

## Les dictionnaires sont des objets

On peut appliquer aux dictionnaires un certain nombre de méthodes spécifiques :

### keys et values

La méthode keys renvoie la liste des clés utilisées dans le dictionnaire :
La méthode values renvoie la liste des valeurs mémorisées dans le dictionnaire :

### has_key

La méthode has_key permet de savoir si un dictionnaire comprend une clé déterminée. On fournit la clé en argument, et la méthode renvoie une valeur 'vraie' ou 'fausse' (en fait, 1 ou 0), suivant que la clé est présente ou pas :
Cette méthode ne fonctionne plus depuis Python 3.x, où il faut utiliser le nom de la clé in nom du dictionnaire.

### items

La méthode items extrait du dictionnaire une liste équivalente de tuples :
Il est donc utilisé pour les "foreach" :

### copy

La méthode copy permet d'effectuer une vraie copie d'un dictionnaire. Il faut savoir en effet que la simple affectation d'un dictionnaire existant à une nouvelle variable crée seulement une nouvelle référence vers le même objet, et non un nouvel objet (aliasing). Par exemple, l'instruction ci-dessous ne définit pas un nouveau dictionnaire (contrairement aux apparences) :
Si nous modifions "invent", alors stock aussi est modifié, et vice-versa (ces deux noms désignent en effet le même objet dictionnaire dans la mémoire de l'ordinateur).
Pour obtenir une vraie copie (indépendante) d'un dictionnaire préexistant, il faut employer la méthode copy :

### update

Il est possible de concaténer deux dictionnaires avec cette méthode :

### sorted

Pour trier un dictionnaire par clé :
Pour trier par valeur :
Pour l'inverse, ajouter : , reverse=True.

## Parcours d'un dictionnaire

Vous pouvez utiliser une boucle for pour traiter successivement tous les éléments contenus dans un dictionnaire, mais attention :
* Au cours de l'itération, ce sont les clés utilisées dans le dictionnaire qui seront successivement affectées à la variable de travail, et non les valeurs.
* L'ordre dans lequel les éléments seront extraits est imprévisible (puisqu'un dictionnaire n'est pas une séquence).
Exemple :
Si vous souhaitez effectuer un traitement sur les valeurs, il vous suffit alors de récupérer chacune d'elles à partir de la clé correspondante :
Cette manière de procéder n'est cependant pas idéale, ni en termes de performances ni même du point de vue de la lisibilité. Il est recommandé de plutôt faire appel à la méthode items décrite à la section précédente :

## Les clés ne sont pas nécessairement des chaînes de caractères

Jusqu'à présent nous avons décrit des dictionnaires dont les clés étaient à chaque fois des valeurs de type string. En fait nous pouvons utiliser en guise de clés n'importe quel type de donnée non modifiable : des entiers, des réels, des chaînes de caractères, et même des tuples.
Considérons par exemple que nous voulions répertorier les arbres remarquables situés dans un grand terrain rectangulaire. Nous pouvons pour cela utiliser un dictionnaire, dont les clés seront des tuples indiquant les coordonnées x,y de chaque arbre :
Vous pouvez remarquer que nous avons allégé l'écriture à partir de la troisième ligne, en profitant du fait que les parenthèses délimitant les tuples sont facultatives (à utiliser avec prudence !).
Dans ce genre de construction, il faut garder à l'esprit que le dictionnaire contient des éléments seulement pour certains couples de coordonnées. Ailleurs, il n'y a rien. Par conséquent, si nous voulons interroger le dictionnaire pour savoir ce qui se trouve là où il n'y a rien, comme par exemple aux coordonnées (2,1), nous allons provoquer une erreur :
Pour résoudre ce petit problème, nous pouvons utiliser la méthode get :
Le premier argument transmis à cette méthode est la clé de recherche, le second argument est la valeur que nous voulons obtenir en retour si la clé n'existe pas dans le dictionnaire.

## Les dictionnaires ne sont pas des séquences

Comme vous l'avez vu plus haut, les éléments d'un dictionnaire ne sont pas disposés dans un ordre particulier. Des opérations comme la concaténation et l'extraction (d'un groupe d'éléments contigus) ne peuvent donc tout simplement pas s'appliquer ici. Si vous essayez tout de même, Python lèvera une erreur lors de l'exécution du code :
Vous avez vu également qu'il suffit d'affecter un nouvel indice (une nouvelle clé) pour ajouter une entrée au dictionnaire. Cela ne marcherait pas avec les listes :
Du fait qu'ils ne sont pas des séquences, les dictionnaires se révèlent donc particulièrement précieux pour gérer des ensembles de données où l'on est amené à effectuer fréquemment des ajouts ou des suppressions, dans n'importe quel ordre. Ils remplacent avantageusement les listes lorsqu'il s'agit de traiter des ensembles de données numérotées, dont les numéros ne se suivent pas.
Exemple :
etc.
Exercices
* Écrivez un script qui crée un mini-système de base de données fonctionnant à l'aide d'un dictionnaire, et dans lequel vous mémoriserez les noms d'une série de copains, leur âge et leur taille. Votre script devra comporter deux fonctions : la première pour le remplissage du dictionnaire, et la seconde pour sa consultation. Dans la fonction de remplissage, utilisez une boucle pour accepter les données entrées par l'utilisateur. Dans le dictionnaire, le nom de l'élève servira de clé d'accès, et les valeurs seront constituées de tuples (âge, taille), dans lesquels l'âge sera exprimé en années (donnée de type entier), et la taille en mètres (donnée de type réel). La fonction de consultation comportera elle aussi une boucle, dans laquelle l'utilisateur pourra fournir un nom quelconque pour obtenir en retour le couple « âge, taille » correspondant. Le résultat de la requête devra être une ligne de texte bien formatée, telle par exemple : « Nom : Jean Dhoute - âge : 15 ans - taille : 1.74 m ».
* Écrivez une fonction qui échange les clés et les valeurs d'un dictionnaire (ce qui permettra par exemple de transformer un dictionnaire anglais/français en un dictionnaire français/anglais). (On suppose que le dictionnaire ne contient pas plusieurs valeurs identiques).
Solution
* #!/usr/bin/env python # coding: utf-8 # Création du dictionnaire dico = while 1: choix = raw_input("Choisissez : (R)emplir - (C)onsulter - (T)erminer : ") if choix.upper == 'T': break elif choix.upper == 'R': nom = raw_input("Entrez le nom (ou <enter> pour terminer) : ") if nom == "": break age = int(raw_input("Entrez l'âge (nombre entier !) : ")) taille = float(raw_input("Entrez la taille (en mètres) : ")) dico[nom] = (age, taille) elif choix.upper == 'C': # Consultation nom = raw_input("Entrez le nom (ou <enter> pour terminer) : ") if nom == "": break if dico.has_key(nom): # le nom est-il répertorié ? item = dico[nom] # consultation proprement dite age, taille = item[0], item[1] print "Nom : %s - âge : %s ans - taille : %s m."\ % (nom, age, taille) else: print "*** nom inconnu ! ***"
* # Échange des clés et des valeurs dans un dictionnaire dico = {'Computer':'Ordinateur', 'Mouse':'Souris', 'Keyboard':'Clavier', 'Hard disk':'Disque dur', 'Screen':'Ecran'} print(dico) dic_inv = for cle in dico: item = dico[cle] dic_inv[item] = cle print(dic_inv)

## Construction d'un histogramme à l'aide d'un dictionnaire

Les dictionnaires constituent un outil très élégant pour construire des histogrammes.
Supposons par exemple que nous voulions établir l'histogramme qui représente la fréquence d'utilisation de chacune des lettres de l'alphabet dans un texte donné. L'algorithme permettant de réaliser ce travail est extraordinairement simple si on le construit sur base d'un dictionnaire :
Nous commençons par créer un dictionnaire vide : lettres. Ensuite, nous allons remplir ce dictionnaire en utilisant les caractères de l'alphabet en guise de clés. Les valeurs que nous mémoriserons pour chacune de ces clés seront les fréquences des caractères correspondants dans le texte. Afin de calculer celles-ci, nous effectuons un parcours de la chaîne de caractères texte. Pour chacun de ces caractères, nous interrogeons le dictionnaire à l'aide de la méthode get, en utilisant le caractère en guise de clé, afin d'y lire la fréquence déjà mémorisée pour ce caractère. Si cette valeur n'existe pas encore, la méthode get doit renvoyer une valeur nulle. Dans tous les cas, nous incrémentons la valeur trouvée, et nous la mémorisons dans le dictionnaire à l'emplacement qui correspond à la clé (c'est-à-dire au caractère en cours de traitement).
Pour fignoler notre travail, nous pouvons encore souhaiter afficher l'histogramme dans l'ordre alphabétique. Pour ce faire, nous pensons immédiatement à la méthode sort, mais celle-ci ne peut s'appliquer qu'aux listes. Qu'à cela ne tienne ! Nous avons vu plus haut comment nous pouvions convertir un dictionnaire en une liste de tuples :
Exercices
* Vous avez à votre disposition un fichier texte quelconque (pas trop gros). Écrivez un script qui compte les occurrences de chacune des lettres de l'alphabet dans ce texte (on ne tiendra pas compte du problème des lettres accentuées)..
* Modifiez le script ci-dessus afin qu'il établisse une table des occurrences de chaque mot dans le texte. Conseil : dans un texte quelconque, les mots ne sont pas seulement séparés par des espaces, mais également par divers signes de ponctuation. Pour simplifier le problème, vous pouvez commencer par remplacer tous les caractères non-alphabétiques par des espaces, et convertir la chaîne résultante en une liste de mots à l'aide de la méthode split.
* Vous avez à votre disposition un fichier texte quelconque (pas trop gros). Écrivez un script qui analyse ce texte, et mémorise dans un dictionnaire l'emplacement exact de chacun des mots (compté en nombre de caractères à partir du début). Lorsqu'un même mot apparaît plusieurs fois, tous ses emplacements doivent être mémorisés : chaque valeur de votre dictionnaire doit donc être une liste d'emplacements.
Solution
* # histogramme nFich = raw_input('Nom du fichier : ') fi = open(nFich, 'r') texte = fi.read # conversion du fichier en une chaîne de caractères fi.close print texte dico = for c in texte: c = c.upper # conversion de toutes les lettres en majuscules dico[c] = dico.get(c, 0) +1 liste = dico.items liste.sort print liste
* nFich = raw_input('Nom du fichier à traiter : ') fi = open(nFich, 'r') texte = fi.read fi.close # afin de pouvoir aisément séparer les mots du texte, on commence # par convertir tous les caractères non-alphabétiques en espaces : alpha = "abcdefghijklmnopqrstuvwxyzéèàùçâêîôûäëïöü" lettres = '' # nouvelle chaîne à construire for c in texte: c = c.lower # conversion de chaque caractère en minuscule if c in alpha: lettres = lettres + c else: lettres = lettres + ' ' # conversion de la chaîne résultante en une liste de mots : mots = lettres.split # construction de l'histogramme : dico = for m in mots: dico[m] = dico.get(m, 0) +1 liste = dico.items # tri de la liste résultante : liste.sort # affichage en clair : for item in liste: print item[0], ":", item[1]
* # encodage d'un texte dans un dictionnaire nFich = raw_input('Nom du fichier à traiter : ') fi = open(nFich, 'r') texte = fi.read fi.close # On considère que les mots sont des suites de caractères faisant partie # de la chaîne ci-dessous. Tous les autres sont des séparateurs : alpha = "abcdefghijklmnopqrstuvwxyzéèàùçâêîôûäëïöü" # construction du dictionnaire : dico = # parcours de tous les caractères du texte : i =0 # indice du caractère en cours de lecture mot ="" # variable de travail : mot en cours de lecture for c in texte: c = c.lower # conversion de chaque caractère en minuscule if c in alpha: # car. alphab. => on est à l'intérieur d'un mot mot = mot + c else: # car. non-alphabétique => fin de mot if mot != "": # afin d'ignorer les car. non-alphabétiques successifs # pour chaque mot, on construit une liste d'indices : if dico.has_key(mot): # mot déjà répertorié : dico[mot].append(i) # ajout d'un indice à la liste else: # mot rencontré pour la 1e fois : dico[mot] =[i] # création de la liste d'indices mot ="" # préparer la lecture du mot suivant i = i+1 # indice du caractère suivant # Affichage du dictionnaire, en clair : for clef, valeur in dico.items: print clef, ":", valeur

## Contrôle du flux d'exécution à l'aide d'un dictionnaire

Il arrive fréquemment que l'on ait à diriger l'exécution d'un programme dans différentes directions, en fonction de la valeur prise par une variable. Vous pouvez bien évidemment traiter ce problème à l'aide d'une série d'instructions if - elif - else , mais cela peut devenir assez lourd et inélégant si vous avez affaire à un grand nombre de possibilités. Exemple :
Les langages de programmation proposent souvent des instructions spécifiques pour traiter ce genre de problème, telles les instructions switch ou case du C ou du Pascal. Python n'en propose aucune, mais vous pouvez vous tirer d'affaire dans bien des cas à l'aide d'une liste, ou mieux encore à l'aide d'un dictionnaire. Exemple :
Les deux instructions ci-dessus pourraient être condensées en une seule, mais nous les laissons séparées pour bien détailler le mécanisme :
* La première instruction définit un dictionnaire dico dans lequel les clés sont les différentes possibilités pour la variable materiau, et les valeurs, les noms des fonctions à invoquer en correspondance. Notez bien qu'il s'agit seulement des noms de ces fonctions, qu'il ne faut surtout pas faire suivre de parenthèses dans ce cas (Sinon Python exécuterait chacune de ces fonctions au moment de la création du dictionnaire).
* La seconde instruction invoque la fonction correspondant au choix opéré à l'aide de la variable materiau. Le nom de la fonction est extrait du dictionnaire à l'aide de la clé, puis associé à une paire de parenthèses. Python reconnaît alors un appel de fonction tout à fait classique et l'exécute.
Vous pouvez encore améliorer la technique ci-dessus en remplaçant cette instruction par sa variante ci-dessous, qui fait appel à la méthode get afin de prévoir le cas où la clé demandée n'existerait pas dans le dictionnaire (vous obtenez de cette façon l'équivalent d'une instruction else terminant une longue série de elif) :
Lorsque la la valeur de la variable "materiau "ne correspond à aucune clé du dictionnaire, c'est la fonction fonctAutre qui est invoquée.

## Différences entre deux dictionnaires

Par exemple pour savoir quels sont les éléments importés :

## Références

* ↑ https://stackoverflow.com/questions/32815640/how-to-get-the-difference-between-two-dictionaries-in-python