Les sélections avec Python

Filtrage et projections avec Python

Quand on travaille avec une table, on ne veut presque jamais tout afficher mais répondre à une question précise, ce qui nous amène à sélectionner. Il en existe deux sortes : la sélection de lignes, qui est un filtrage, et la sélection de colonnes, que l’on appelle projection dans le jargon des bases de données. Et bien sûr, on peut combiner les deux.

Nous expliquerons ici comment faire avec Python. Le niveau est celui d’une classe de première. À compléter avec les exercices de sélection (2 à 5).

 

Données

Nous nous appuierons sur la table issue du fichier russes.csv que vous trouverez en page d’agrégations avec Python. Sans grande originalité, nous l’appelons table. C’est une liste de dictionnaires.

 

Sélection de lignes

Nous conservons certaines lignes selon une condition. Par exemple, nous souhaitons garder les écrivains.

Définissons une fonction filter_litterature.

def filtrer_litterature(table):
    resultat = []

    for personne in table:
        if personne["Domaine"] == "littérature":
            resultat.append(personne)
        return resultat

L’idée est de tester une condition sur chaque ligne. Le résultat est une nouvelle table (liste de dictionnaires).

Rappelons que append ajoute un élément à la fin d’une liste.

Utilisons à présent cette fonction pour afficher le résultat.

litterature = filtrer_litterature(table)
for p in litterature:
    print(p)

Résultat :

{'Nom': 'Tolstoï', 'Domaine': 'littérature', 'Naissance': '1828', 'Décès': '82'}
{'Nom': 'Dostoïevski', 'Domaine': 'littérature', 'Naissance': '1821', 'Décès': '59'}
{'Nom': 'Tourgueniev', 'Domaine': 'littérature', 'Naissance': '1818', 'Décès': '64'}
{'Nom': 'Gorki', 'Domaine': 'littérature', 'Naissance': '1868', 'Décès': '68'}

écrivains

Variante possible :

def filtrer_litterature(table):
    return [p for p in table if p["Domaine"] == "littérature"]

Une utilisation habituelle des sélections est d’éliminer des enregistrements mal renseignés (nettoyage de données).

 

Sélection de colonnes

Conservons certaines informations dans chaque ligne. Par exemple, gardons seulement les noms.

def extraire_noms(table):
    noms = []

    for personne in table:
        noms.append(personne["Nom"])
    return noms
liste_noms = extraire_noms(table)
for nom in liste_noms:
    print(nom)

Donc, on parcourt la table, on extrait une seule colonne et le résultat est une liste simple. On passe d’une table à une liste. Résultat (premières lignes seulement)  :

Lénine
Khrouchtchev
Pavlov

Etc.

Variante plus compacte :

def extraire_noms(table):
    return [p["Nom"] for p in table]

Autre exemple. Gardons le nom et le domaine.

def extraire_nom_domaine(table):
    resultat = []

    for personne in table:
        ligne = {
            "Nom": personne["Nom"],
            "Domaine": personne["Domaine"]
        }
        resultat.append(ligne)
    return resultat
table_reduite = extraire_nom_domaine(table)

Utilisation :

for ligne in table_reduite:
    print(ligne)

On obtient une table simplifiée qui commence ainsi :

{'Nom': 'Lénine', 'Domaine': 'politique'}
{'Nom': 'Trotski', 'Domaine': 'politique'}

Etc.

 

Double sélection

Combinons un filtre et une projection en affichant les noms des écrivains morts après 65 ans.

def selection_complexe(table):
    resultat = []

    for personne in table:
        if personne["Domaine"] == "littérature" and int(personne["Décès"]) > 65:
            resultat.append(personne["Nom"])
    return resultat

Utilisation :

liste = selection_complexe(table)
for nom in liste:
    print(nom)

En sortie, on obtient l'affichage des noms Tolstoï et Gorki.

Là encore, on peut choisir une autre technique en découpant la fonction en deux :

def filtrer(table):
    return [p for p in table if p["Domaine"] == "littérature" and int(p["Décès"]) > 65]

def projeter(table):
    return [p["Nom"] for p in table]

resultat = projeter(filtrer(table))

 

sélection