Traitement de données en tables
La possibilité de recueillir, traiter et d'analyser de très grandes quantités de données est une des caractéristiques majeures d'un monde numérique. Des logiciels spécialisés permettent d'optimiser ces traitements, mais les principles de base peuvent en être abordées en utilisant des outils de programmation simples.
Avant de commencer il est nécessaire d'avoir vu jusqu'au bout la partie sur les types structurés , y compris la partie approfondissement, notamment la définition de liste en compréhension.
Rassembler les réponses aux exercices dans un fichier texte qui sera rendu via l'ENT
Sauf indication contraire, les données utilisées dans cette page sont issues de Wikipedia
Traitement de données en liste
Dans un premier temps nous allons récapituler et approfondir quelques notions déjà présentées pour traiter des données simples rangées dans une liste.
Les données utilisées comme exemple consistent en une liste de noms d'arbres.
- arbres=["peuplier", "pin", "if", "pommier", "sapin", "chêne", "cèdre", "aulne","noyer","marronier","frêne", "hêtre", "orme"]
Recherche de données en fonction d'un critère
La définition de liste en compréhension permet d'obtenir une sous-liste d'éléments respectant certains critères. Utiliser la définition en compréhension pour faire les exercices suivants
(revoir éventuellement la partie
opérations sur chaînes dans les notions de base.)
Tri et tri avancé
Le tri d'une liste peut être réalisé à l'aide de la méthode
sort pour un tri "en place", ou à l'aide de la fonction
sorted pour obtenir une copie triée. Dans cette partie nous utiliserons plutôt
sorted pour conserver les données initiales en l'état, mais
sorted offre les mêmes possibilités.
Tri simple
L'application de la fonction
sorted à notre liste d'arbres nous en fournit une copie triée dans l'ordre alphabétique (ou plus exactement dans l'ordre lexicographique) croissant.
- arbres_tries=sorted(arbres)
Il est possible d'obtenir un tri dans l'ordre inverse en ajoutant
reverse=True dans les paramètres.
- arbres_tries=sorted(arbres,reverse=True)
Clé de tri
On peut vouloir trier les éléments d'une liste en fonction d'un autre critère que celui qui est "naturel" du point de vue de Python.
Par exemple, supposons qu'on veuille trier la liste en fonction de la longueur du nom de l'arbre. Cette longueur peut être déterminée à l'aide de la fonction len .
Il suffit alors d'indiquer le nom de cette fonction dans les paramètres de la fonction sorted , de la façon suivante :
- arbres_tries=sorted(arbres,key=len)
On dit que
len est la
clé (key) de tri. Cela signifie que l'opération de tri se fait en deux temps : la fonction
len est d'abord appliquée à chacun des éléments de la liste à trier, puis le tri est effectué en fonction des résultats obtenus.
La fonction utilisée comme clé peut être une fonction Python native comme len , ou bien une fonction créée pour l'occasion.
Exemple :
- def nb_a(s):
- return s.count('a')
- trie=sorted(arbres,key=nb_a,reverse=True)
Dans cet exemple on crée une fonction appelée
nb_a qui renvoie le nombre d'apparitions de la lettre 'a' dans la chaîne qu'on lui passe en paramètre.
Le résultat du tri est donc une liste dans laquelle les noms d'arbres sont triés en fonction du nombre de 'a' qu'ils contiennent, par ordre décroissant puisqu'on a ajouté
reverse=True .
>>>trie
['catalpa', 'platane', 'sapin', 'aulne', 'marronier', 'bouleau', 'peuplier', 'pin', 'if', 'pommier', 'chêne', 'cèdre', 'noyer', 'frêne', 'hêtre', 'orme', 'olivier', 'tilleul']
Les exercices suivants nécessitent d'associer recherche en fonction d'un critère et tri.
Données en 'table'
Pour présenter un intérêt, les données devront généralement être plus riches qu'une simple liste de noms, et donc plus complexes.
Une donnée complexe rassemble plusieurs informations relatives à une même entité, chacune des informations étant identifiée par un descripteur.
Une grande quantité de données ayant les mêmes descripteurs est fréquemment appelée 'table', parce que nous la visualisons plus facilement sous cette forme.
Création d'une table de données
Pour commencer à employer le langage des bases de données, par la suite l'ensemble des informations relatives à une entité donnée sera appelé un enregistrement , et les données qui composent un enregistrement seront appelées champs de cet enregistrement.
Par exemple le tableau ci-dessous rassemble quelques information concernant des oeuvres d'Agatha Christie.
La première ligne contient les descripteurs des champs.
A partir de la deuxième ligne, chaque ligne du tableau est associée à une oeuvre, dont les descripteurs sont son titre, son type, son personnage principal et son année de parution.
Pour pouvoir analyser ces informations à l'aide d'un programme, il faut les affecter à des variables. Afin de pouvoir maintenir le lien entre les informations d'une même ligne, constituant un même enregistrement, il est nécessaire de les placer dans une variable de type structuré.
La structure que nous utiliserons cette année pour stocker un enregistrement sera un
dictionnaire, dont les clés seront les descripteurs des champs.
Les données de la deuxième ligne du tableau pourront ainsi être enregistrées de la manière suivante :
- oeuvre1={"titre":"Un cadavre dans la bibliothèque","type":"roman","personnage":"Miss Marple","annee":1929}
ou bien
- oeuvre1=dict(titre="Un cadavre dans la bibliothèque",type="roman",personnage="Miss Marple",annee=1929)
Le titre de l'oeuvre sera alors désigné par
oeuvre1["titre"] , son année de parution par
oeuvre1["annee"] ,...
Un nouveau dictionnaire utilisant les mêmes clés devra être créé pour chacune des lignes du tableau. Plutôt que de créer un grand nombre de noms de variable
oeuvre1, oeuvre2... pour stocker les enregistrements, il est beaucoup plus pratique de strocker les enregistrements dans une liste.
Le code ci-dessous crée une nouvelle liste appelée
oeuvres et y place toutes les données du tableau : on obtient une liste de dictionnaires.
- christie=[]
- christie.append(dict(titre="Un cadavre dans la bibliothèque",type="roman",personnage="Miss Marple",annee=1929))
- christie.append(dict(titre="La Mystérieuse Affaire de Styles",type="roman",personnage="Hercule Poirot",annee=1920))
- christie.append(dict(titre="Miss Marple au club du Mardi",type="nouvelles",personnage="Miss Marple",annee=1942))
- christie.append(dict(titre="Cinq Petits Cochons",type="roman",personnage="Hercule Poirot",annee=1942))
- christie.append(dict(titre="Les Travaux d'Hercule",type="nouvelles",personnage="Hercule Poirot",annee=1947))
- christie.append(dict(titre="L'affaire Protheroe",type="roman",personnage="Miss Marple",annee=1930))
- christie.append(dict(titre="Le crime est notre affaire",type="nouvelles",personnage="Tommy et Tuppence",annee=1929))
- christie.append(dict(titre="Le Meurtre de Roger Ackroyd",type="roman",personnage="Hercule Poirot",annee=1926))
- christie.append(dict(titre="N ou M ?",type="roman",personnage="Tommy et Tuppence",annee=1941))
(ce code est à copier dans l'éditeur Python afin de pouvoir faire la suite)
A la ligne 1, on crée une liste vide appelée christie. A chacune des lignes suivantes, on crée un enregistrement sous forme de dictionnaire en utilisant les données d'une ligne du tableau, et on l'ajoute à la liste oeuvres, à l'aide de la méthode append
(nous verrons plus tard comment automatiser l'importation de données depuis un tableur, au lieu d'avoir à écrire une ligne de code par enregistrement).
Le titre de la 2ème oeuvre de la liste, par exemple, sera alors désigné par christie[1]["titre"]
Exemple de parcours de la liste en affichant les valeurs de certains champs :
- for oeuvre in christie:
- print("Le personnage de l'oeuvre",oeuvre["titre"],"parue en",oeuvre["annee"],"est",oeuvre["personnage"])
Extraction de données en fonction d'un critère
Supposons qu'on veuille obtenir une liste de toutes les oeuvres de notre table christie qui sont des romans.
On pourra écrire tout simplement
- romans=[oeuvre for oeuvre in christie if oeuvre["type"]=="roman"]
La nouvelle liste
romans est alors une liste de dictionnaires contenant tous les enregistrements correspondant à des oeuvres qui sont des romans.
Si on est intéressé seulement par les titres de ces oeuvres on écrira plutôt
- romans=[oeuvre["titre"] for oeuvre in christie if oeuvre["type"]=="roman"]
La nouvelle liste
romans est alors une liste de chaînes de caractères qui sont les titres des romans.
Tri des données en fonction d'un descripteur
La liste
christie est assez désordonnée. On pourrait vouloir par exemple la trier en fonction du nom du personnage principal.
Comme vu avec les listes dans la première partie, on va utiliser une fonction
clé de tri qui va renvoyer, pour chaque enregistrement, la valeur selon laquelle on veut réaliser le tri.
Pour trier la liste en fonction du nom du personnage principal, notre fonction va donc s'appliquer à un enregistrement de la liste et retourner le nom de son personnage:
-
def perso(oeuvre):
- return oeuvre["personnage"]
puis on triera la liste en utilisant cette fonction comme clé de tri :
- triperso=sorted(christie,key=perso)
>>> triperso
[{'titre': 'La Mystérieuse Affaire de Styles', 'type': 'roman', 'personnage': 'Hercule Poirot', 'annee': 1920}, {'titre': 'Cinq Petits Cochons', 'type': 'roman', 'personnage': 'Hercule Poirot', 'annee': 1942}, {'titre': "Les Travaux d'Hercule", 'type': 'nouvelles', 'personnage': 'Hercule Poirot', 'annee': 1947}, {'titre': 'Le Meurtre de Roger Ackroyd', 'type': 'roman', 'personnage': 'Hercule Poirot', 'annee': 1926}, {'titre': 'Un cadavre dans la bibliothèque', 'type': 'roman', 'personnage': 'Miss Marple', 'annee': 1929}, {'titre': 'Miss Marple au club du Mardi', 'type': 'nouvelles', 'personnage': 'Miss Marple', 'annee': 1942}, {'titre': "L'affaire Protheroe", 'type': 'roman', 'personnage': 'Miss Marple', 'annee': 1930}, {'titre': 'Le crime est notre affaire', 'type': 'nouvelles', 'personnage': 'Tommy et Tuppence', 'annee': 1929}, {'titre': 'N ou M ?', 'type': 'roman', 'personnage': 'Tommy et Tuppence', 'annee': 1941}]
Il est bien entendu possible de combiner extraction en fonction d'un critère, et tri :
Tri sur plusieurs champs
Supposons qu'on veuille obtenir une liste des oeuvres triées en fonction de leur personnage principal et de leur date de parution.
On peut pour cela réaliser plusieurs tris successifs selon chacun des critères :
-
def perso(oeuvre):
- return oeuvre["personnage"]
- def annee(oeuvre):
- return oeuvre["annee"]
- tri1=sorted(christie,key=annee)
- tri2=sorted(tri1,key=perso)
ou, en version plus compacte (mais pas forcément plus lisible) :
-
def perso(oeuvre):
- return oeuvre["personnage"]
- def annee(oeuvre):
- return oeuvre["annee"]
- tri=sorted(sorted(christie,key=annee),key=perso)
Attention : en cas de tris successifs les critères de tri doivent être appliqués par ordre de priorité croissante, le plus prioritaire en dernier.
Par exemple si on souhaite que la liste finale apparaisse triée d'abord par personnage, puis par type d'oeuvre, puis par année de parution, on doit trier d'abord sur l'année, puis sur le type, puis sur le personnage.
Il est aussi possible de réaliser un tri multicritère en utilisant une seule fonction de tri : il faut alors que celle-ci renvoie, pour chaque enregistrement les valeurs des champs concernés, sous forme d'un tuple, par ordre de priorité décroissante (critère le plus prioritaire en premier).
Ainsi, pour un tri par personnage et par année de parution :
Pour trier prioritairement selon le personnage, la fonction clé de tri sera de la forme :
- def criteres(oeuvre):
- return oeuvre['personnage'],oeuvre['année']
Avec cette fonction de tri, le code
- doubletri=sorted(christie,key=criteres)
- for o in doubletri:
- print(list(o.values()))
nous donne
['La Mystérieuse Affaire de Styles', 'roman', 'Hercule Poirot', 1920]
['Le Meurtre de Roger Ackroyd', 'roman', 'Hercule Poirot', 1926]
['Cinq Petits Cochons', 'roman', 'Hercule Poirot', 1942]
["Les Travaux d'Hercule", 'nouvelles', 'Hercule Poirot', 1947]
['Un cadavre dans la bibliothèque', 'roman', 'Miss Marple', 1929]
["L'affaire Protheroe", 'roman', 'Miss Marple', 1930]
['Miss Marple au club du Mardi', 'nouvelles', 'Miss Marple', 1942]
['Le crime est notre affaire', 'nouvelles', 'Tommy et Tuppence', 1929]
['N ou N ?','roman','Tommy et Tuppence',1941]
(tri par personnage puis année de parution)
alors qu'avec la fonction de tri
- def criteres(oeuvre):
- return oeuvre['année'],oeuvre['personnage']
on obtiendra
['La Mystérieuse Affaire de Styles', 'roman', 'Hercule Poirot', 1920]
['Le Meurtre de Roger Ackroyd', 'roman', 'Hercule Poirot', 1926]
['Un cadavre dans la bibliothèque', 'roman', 'Miss Marple', 1929]
['Le crime est notre affaire', 'nouvelles', 'Tommy et Tuppence', 1929]
["L'affaire Protheroe", 'roman', 'Miss Marple', 1930]
['N ou N ?','roman','Tommy et Tuppence',1941]
['Cinq Petits Cochons', 'roman', 'Hercule Poirot', 1942]
['Miss Marple au club du Mardi', 'nouvelles', 'Miss Marple', 1942]
["Les Travaux d'Hercule", 'nouvelles', 'Hercule Poirot', 1947]
(tri par année de parution puis personnage).
Avec cette deuxième méthode la fonction clé de tri doit renvoyer les critères par ordre de priorité décroissante (le plus prioritaire en premier).
Importation de données
Attention : pour cette partie il n'est pas possible d'utiliser un environnement de développement Python en ligne car celui-ci ne sera pas (et c'est heureux) autorisé à accéder aux fichiers se trouvant sur le disque dur de l'ordinateur ou le serveur réseau du lycée.
Il faut donc utiliser un environnement installé localement (Pyzo ou Idle par exemple).
Le format CSV
Le format de fichier CSV est un des plus anciens formats permettant l'échange de données structurées entre des logiciels ou des systèmes d'exploitation différents. Il s'agit essentiellement d'un fichier texte pur reprenant l'organisation en "lignes" et "colonnes" d'un tableau, les lignes étant séparés par un saut de ligne (code /n ou /r/n) et les colonnes par un caractère spécifique : virgule, point-virgule, tabulation (code /t)...
Un fichier CSV peut être ouvert et édité par n'importe quel éditeur de texte pur, mais aussi par les tableurs, et réciproquement les tableurs peuvent exporter une feuille de calcul au format CSV.
LibreOffice Calc donne ainsi beaucoup d'options pour lire ou écrire du CSV: choix des délimiteurs, de l'éncodage, de la langue (qui est associée à des paramètres locaux comme le séparateur décimal ou le format des dates)
Importation avec la bibliothèque csv
Exemple du fichier 'christie'
A titre d'exemple on va utiliser un fichier CSV contenant les données sur des oeuvres d'Agatha Christie utilisées précédemment.
Lorsqu'un programme doit accéder à des fichiers, il est nécessaire qu'il puisse les trouver. On peut utiliser pour cela la bibliothèque os qui permet de naviguer dans le système de fichier.
Pour déterminer quel est l'emplacement par défaut, où les programmes exécutés depuis l'éditeur iront chercher les fichiers, exécuter les commandes suivantes, en mode interactif:
>>>import os
>>>os.getcwd()
L'emplacement renvoyé par la commande
os.getcwd(() est le dossier de travail par défaut. Les fichiers placés dans ce dossier seront donc accessibles aux programmes Python exécutés depuis l'éditeur (ce dossier n'est pas forcément le même que celui où l'éditeur enregistre par défaut les fichiers Python). C'est donc là qu'il faudra placer les fichiers CSV.
Il est aussi possible de changer le dossier de travail en utilisant la fonction
os.chdir() en donnant comme paramètre le chemin du dossier qu'on souhaite utiliser.
Sur le réseau du lycée il est possible d'utiliser votre dossier personnel prenom.nom dont le chemin est U:/prenom.nom.
Télécharger le fichier christie.csv et l'enregistrer dans le dossier de travail.
Le contenu du fichier est le suivant :
On constate que le séparateur de données est un point virgule et que la première ligne contient les noms des descripteurs de champs.
L'élément DictReader de la bibliothèque csv permet de transformer facilement le contenu de ce fichier en une liste de dictionnaires :
- from csv import DictReader
- oeuvres=[]
- fichiercsv=open('christie.csv', newline='', encoding='utf-8')
- lecteur=DictReader(fichiercsv, delimiter=';')
- for ligne in lecteur:
- oeuvres.append(dict(ligne))
- fichiercsv.close()
- print(oeuvres)
La ligne 3 ouvre le fichier et l'appelle
fichiercsv. Il faut indiquer le nom du fichier et, obligatoirement,
newline='' . L'indication de l'encodage à l'aide du paramètre
encoding est facultative mais recommandée dès que les données contiennent des caractères non-ASCII (comme, ici, les caractères accentués). Il ne faudra pas oublier de fermer le fichier une fois qu'il aura été lu (ici, à la ligne 7).
A la ligne 4 l'objet permettant de lire les lignes du fichier pour en faire des dictionnaires est créé. C'est ici qu'on indique le séparateur de données (';' pour nous), avec le paramètres
delimiter .
La boucle qui suit, aux lignes 5 et 6, permet de lire le fichier ligne par ligne, d'enregister les données de chaque ligne dans un dictionnaire et d'ajouter celui-ci à la liste
oeuvres.
Après l'exécution de ce code, la liste oeuvres contient tous les enregistrements initialement contenus dans le fichier CSV, sous forme de dictionnaires dont les clés sont les descripteurs donnés dans la première ligne du fichier CSV.
Si les noms des descripteurs ne sont pas donnés dans le fichier CSV, on peut les fournir sous la forme d'une liste, au moment de la création du lecteur (paramètre fieldnames, c'est à dire 'noms de champs').
Exécuter par exemple le code ci-dessous, après avoir supprimé la première ligne du fichier christie.csv (à l'aide du bloc-notes par exemple)
- from csv import DictReader
- oeuvres=[]
- descripteurs=['titre','type','personnage','annee']
- fichiercsv=open('christie.csv', newline='', encoding='utf-8')
- lecteur=DictReader(fichiercsv, delimiter=';',fieldnames=descripteurs)
- for ligne in lecteur:
- oeuvres.append(dict(ligne))
- fichiercsv.close()
- print(oeuvres)
La liste
descripteurs contenant les descripteurs est alors créé à la ligne 3, puis elle est passée comme paramètre
fieldnames à la ligne 5.
Format des données importées
La liste oeuvres qui vient d'être créée par importation est légèrement différente de la liste christie précédemment créée par déclaration.
Dans la liste importée, tous les champs d'un enregistrement sont de type str (chaîne de caractères) alors que dans la liste christie les années étaient de type int.
>>>type(christie[0]['annee'])
<class 'int'>
>>>type(oeuvres[0]['annee'])
<class 'str'>
Ce n'est pas toujours un problème, mais il faut en être conscient car on ne peut pas effectuer tout à fait les mêmes traitements avec les deux formats, ni obtenir tout à fait les mêmes résultats lors des tris. Par exemple 9 < 10 , mais '9' > '10'.
Quand on importe des données avec la bibliothèque csv , tous les champs sont des chaînes de caractères.
Si on souhaite obtenir un des champs des enregistrements dans un format numérique, on peut le convertir au moment de l'importation (ligne 6 ci-dessous):
- from csv import DictReader
- oeuvres=[]
- fichiercsv=open('christie.csv', newline='', encoding='utf-8')
- lecteur=DictReader(fichiercsv, delimiter=';')
- for ligne in lecteur:
- ligne['annee']=int(ligne['annee'])
- oeuvres.append(dict(ligne))
- fichiercsv.close()
- print(oeuvres)
Cette méthode n'est pas sans risque car il est toujours possible que pour certains enregistrement, le contenu du champ ne puisse pas être converti en nombre, par exemple parce que le champ a été laissé vide.
Dans ce cas l'erreur provoquée par la tentative de conversion arrêtera le programme, sans que le fichier ait été refermé, ce qui n'est pas une bonne chose.
Pour éviter ce problème, on peut envelopper la tentative de conversion dans une instruction try: ... except ...: :
- from csv import DictReader
- oeuvres=[]
- fichiercsv=open('christie.csv', newline='', encoding='utf-8')
- lecteur=DictReader(fichiercsv, delimiter=';')
- for ligne in lecteur:
- try:
- ligne['annee']=int(ligne['annee'])
- except ValueError:
- ligne['annee']=-1
- oeuvres.append(dict(ligne))
- fichiercsv.close()
- print(oeuvres)
Avec cette instruction
try: ... except ...: , le bloc de code qui suit
try: est
tenté.
En cas d'erreur (ici c'est une ValueError qui risque de se produire) le bloc qui suit except...: est exécuté, puis le programme se poursuit normalement.
Avec le code ci-dessus, si la chaîne de caractères contenue dans le champ annee ne représente pas un entier, on donne au champ annee la valeur -1, qui ne risque pas d'être prise par la suite pour une donnée valide, mais est du même format que les annees valides dans les autres enregistrements : lors d'un tri sur ce champ, les enregistrements pour lesquels il est invalide ne causeront pas d'erreurs, et seront rangées ensemble.
On aurait pu aussi être plus radical et décider de ne pas inclure les enregistrements dont le champ annee n'est pas valide. Pour cela il suffit de placer la ligne qui ajoute l'enregistrement à la table oeuvres dans le bloc try:
- from csv import DictReader
- oeuvres=[]
- fichiercsv=open('christie.csv', newline='', encoding='utf-8')
- lecteur=DictReader(fichiercsv, delimiter=';')
- for ligne in lecteur:
- try:
- ligne['annee']=int(ligne['annee'])
- oeuvres.append(dict(ligne))
- except ValueError:
- pass
- fichiercsv.close()
- print(oeuvres)
pass veut dire : ne rien faire.
Cohérence des données
On a signalé ci-dessous l'importance de l'homogénéité de type pour un même champ dans une table.
De même, pour les données qui sont des chaînes de caractères, l'homogénéité des formulations est importante : par exemple, 'nouvelles' et 'recueil de nouvelles' auront généralement le même sens, mais ne sont pas identiques pour un programme informatique. Il faut donc éviter d'utiliser soit l'un soit l'autre comme valeur d'un même champ
De manière générale, il est important que les valeurs d'un même champ dans les différents enregistrements d'une table puisse être comparées entre elles.
Les données numériques devront ainsi être de préférence de type numérique (int ou float en Python) et exprimées dans la même unité.
Pour les données désignant des entités ou des catégories, chaque entité ou catégorie doit avoir autant que possible un identifiant unique.
Lors de la conception de la table, on peut faciliter le respect de ces règles en définissant, pour chacun des champs concernés, son format et le domaine de valeurs autorisé pour ce champ.
Pour résoudre les problèmes de cohérence on est généralement amené à faire de nombreux traitements sur des chaînes de caractères (suppression ou remplacement de caractères ou de groupes de caractères).
Python propose de nombreuses méthodes de chaînes de caractère facilitant ce travail.
(voir en particulier les méthodes split , lstrip , rstrip , replace , lower , upper .)
Comme ce sont des méthodes, et qu'une str est immuable, toutes les opérations listées ci-dessus s'utilisent selon la syntaxe :
nouvelle_chaine = ancienne_chaine.nom_de_la_methode(paramètres_eventuels)
(
split renvoie une liste de chaînes et non une chaîne)
Le format Json (partie facultative)
Le format JSON est un format d'échange de données plus récent et plus élaboré que le CSV. Il permet d'enregister au format texte des données structurées, quasiment sans limitation sur la complexité de leur structure.
La bibliothèque Python json permet de lire des données au format json.
A titre d'exemple, télécharger le fichier de données pollens.json et l'enregister localement. Ce fichier est issu de data.grandlyon.com (mis à jour le 13/10/2020). Dans la version d'origine, toutes les données sont écrites sur une seule ligne. Le fichier fourni ici a été rendu plus lisible pour l'être humain à l'aide d'un "embellisseur" json en ligne.
Ouvrir le fichier dans un éditeur de texte pour visualiser sa structure: on peut constater qu'il utilise un format 'clé:valeur' similaire à celui des dictionnaires Python.
Le code ci-dessous permet d'ouvrir le fichier et de le charger dans la variable "donnees" en respectant sa structure.
- import json
- f=open('pollens.json')
- brut=f.read();
- f.close()
- donnees=json.loads(brut)