La recherche avec Python

Recherche dans une table avec Python

Quand on travaille avec des données, on fait souvent la même chose : chercher une information précise dans un tableau.

Ici, nous emploierons Python mais il existe des centaines d’autres moyens pour réaliser ce type de travail.

Nous nous situons à un niveau d’initiation, par exemple celui d’un niveau première, cours de NSI.

 

Données et chargement

Notre jeu de données est un fichier CSV de personnalités nées au dix-neuvième siècle dans l’empire russe.

Quatre colonnes : le nom de la personne, le principal domaine pour lequel elle est célèbre, son année de naissance et l’âge auquel elle est décédée. Les champs sont délimités par des virgules et sont correctement renseignés, à l'exception du domaine d’activité de Zadkine qui a été oublié.

Nom,Domaine,Naissance,Décès
Lénine,politique,1870,53
Trotski,politique,1879,60
Khrouchtchev,politique,1894,77
Pavlov,médecine,1849,86
Tolstoï,littérature,1828,82
Dostoïevski,littérature,1821,59
Tourgueniev,littérature,1818,64
Gorki,littérature,1868,68
Chagall,peinture,1887,97
Malevitch,peinture,1879,56
Kandinsky,peinture,1866,78
Prokofiev,musique,1891,61
Stravinsky,musique,1882,88
Zadkine,,1888,79
Mendeleïev,chimie,1834,72

Chargeons le fichier. Son nom est russes.csv.

import csv

fichier = open("russes.csv")
table = list(csv.DictReader(fichier))

Théoriquement, les données sont chargées (nous verrons un peu plus bas qu’en pratique ce n’est pas toujours le cas).

table est une liste de dictionnaires (voir le module csv de Python).

 

Recherche

Reprenons le script d’importation et complétons-le.

import csv

fichier = open("russes.csv", encoding="utf-16")
table = list(csv.DictReader(fichier))

for personne in table:
    if personne["Nom"] == "Lénine":
        age = personne["Décès"]
        print("Lénine est mort à", age, "ans.")

Résultat :

Lénine est mort à 53 ans.

Lénine

Ici, nous avons dû préciser encoding="utf-16" car nous avons créé le fichier avec le bloc-notes de Windows. Retenez qu’en cas de messages d’erreur, c’est un bon réflexe de préciser un encodage (essayez utf-8 et utf-16).

Nous avons utilisé une boucle for. Si plusieurs personnes s’étaient appelées Lénine, Python aurait affiché plusieurs réponses. C’est logique, mais ce n’est pas toujours ce qu’on souhaite obtenir. Pour s’arrêter au premier enregistrement trouvé, afin de gagner du temps ou pour toute autre raison, il aurait fallu écrire break après la ligne print.

Rappelons tout de même que dans une vraie base de données, il existe une clé unique pour chaque enregistrement (numéro de sécurité sociale, matricule, référence produit…). Si notre liste avait été très longue, et en l’absence d’identifiant unique, nous aurions indiqué une double condition sur le nom et l’année de naissance pour limiter le risque d’homonymie.

Autre exemple : écrire une fonction (puisqu’au lycée on aime présenter les scripts sous forme de fonction !) qui affiche le nom des personnalités nées entre 1820 et 1840.

def nes_entre(table, annee_min, annee_max):
    resultat = []

    for personne in table:
        annee_naissance = int(personne["Naissance"])

        if annee_min <= annee_naissance <= annee_max:
    resultat.append(personne["Nom"])

return resultat

Le programme de première précise de chercher les lignes d’une table vérifiant des critères exprimés en logique propositionnelle. Nous avons vu des comparaisons. Ajoutons la conjonction (et). Soit les écrivains morts après 65 ans :

if personne["Domaine"] == "littérature" and int(personne["Décès"]) > 65:

Enfin, la disjonction (ou). Soit les compositeurs et les peintres :

if personne["Domaine"] == "musique" or personne["Domaine"] == "peinture":

 

Champs non renseignés

À titre d’exemple, écrivons un script pour afficher les noms des personnalités dont le domaine d’activité a été oublié.

La fonction pourrait être la suivante :

def domaines_non_renseignes(table):
    noms_a_completer = []
   
    for personne in table:
        if personne["Domaine"] == "":
            noms_a_completer.append(personne["Nom"])
   
    print("Nombre de domaines non renseignés :", len(noms_a_completer))
   
    if len(noms_a_completer) > 0:
        print("Personnes concernées :")
        for nom in noms_a_completer:
            print("-", nom)

   
    return noms_a_completer

Ce type d’exercice est très important. Avant de réaliser une analyse de données, il y a toujours une étape assez longue de nettoyage. La recherche de valeurs non renseignées en fait partie. Ensuite, selon l’étude à réaliser, soit on supprime les enregistrements incomplets, soit on les corrige.

En l’occurrence, la sortie est la suivante :

Nombre de domaines non renseignés : 1
Personnes concernées :
- Zadkine

Ensuite, on peut préciser que le domaine d’activité de Zadkine était la sculpture, soit dans la liste en mémoire, soit dans le fichier CSV (mais ce n’est pas le sujet de cette page).

 

condition