Aller au contenu

Partie 2 : Opérations sur les tables (recherche, tri, sélection)


La projection consiste à ne garder que certaines colonnes d'une table.

À partir d'une table complète :

table = [
{"nom": "Dupont", "prenom": "Marie", "age": 16, "ville": "Lyon"},
{"nom": "Martin", "prenom": "Léo", "age": 17, "ville": "Paris"},
{"nom": "Durand", "prenom": "Emma", "age": 16, "ville": "Lille"}
]

On peut extraire uniquement les colonnes "prenom" et "ville" :

projection = [{"prenom": e["prenom"], "ville": e["ville"]} for e in table]

Résultat :

[
{"prenom": "Marie", "ville": "Lyon"},
{"prenom": "Léo", "ville": "Paris"},
{"prenom": "Emma", "ville": "Lille"}
]
def projeter(table, colonnes):
"""Renvoie une nouvelle table ne contenant que les colonnes indiquées."""
return [{col: ligne[col] for col in colonnes} for ligne in table]
resultat = projeter(table, ["nom", "age"])

Le filtrage consiste à ne garder que les lignes qui vérifient une condition.

# Élèves de 16 ans
jeunes = [e for e in table if e["age"] == 16]

On peut combiner les conditions avec and, or, not :

# Élèves de 16 ans habitant Lyon
critere = [e for e in table if e["age"] == 16 and e["ville"] == "Lyon"]
# Élèves habitant Paris ou Lyon
grandes_villes = [e for e in table if e["ville"] in ["Paris", "Lyon"]]
def filtrer(table, attribut, valeur):
"""Renvoie les lignes où l'attribut a la valeur donnée."""
return [ligne for ligne in table if ligne[attribut] == valeur]
lyonnais = filtrer(table, "ville", "Lyon")

La fonction sorted() permet de trier un tableau de dictionnaires selon un attribut :

# Tri par âge (croissant)
par_age = sorted(table, key=lambda e: e["age"])
# Tri par nom (alphabétique)
par_nom = sorted(table, key=lambda e: e["nom"])
# Tri par âge décroissant
par_age_desc = sorted(table, key=lambda e: e["age"], reverse=True)

La méthode sort() modifie la table directement (sans en créer une nouvelle) :

table.sort(key=lambda e: e["nom"])

Le tri de Python est stable : si deux éléments ont la même valeur pour le critère de tri, leur ordre relatif d'origine est conservé.

table = [
{"nom": "Dupont", "prenom": "Marie", "age": 16},
{"nom": "Martin", "prenom": "Léo", "age": 16},
{"nom": "Durand", "prenom": "Emma", "age": 17}
]
par_age = sorted(table, key=lambda e: e["age"])
# Marie et Léo ont 16 ans : ils restent dans l'ordre d'origine

Un doublon est un enregistrement qui apparait deux fois (ou plus) dans la table. On peut chercher les doublons sur un attribut particulier ou sur l'ensemble des attributs.

def doublons(table, attribut):
"""Renvoie les valeurs de l'attribut qui apparaissent plus d'une fois."""
vus = []
en_double = []
for ligne in table:
valeur = ligne[attribut]
if valeur in vus and valeur not in en_double:
en_double.append(valeur)
vus.append(valeur)
return en_double
table = [
{"nom": "Dupont", "age": 16},
{"nom": "Martin", "age": 17},
{"nom": "Dupont", "age": 15},
{"nom": "Durand", "age": 16}
]
print(doublons(table, "nom")) # ['Dupont']
print(doublons(table, "age")) # [16]
def sans_doublons(table, attribut):
"""Renvoie une table sans doublons sur l'attribut donné (garde le premier)."""
vus = []
resultat = []
for ligne in table:
if ligne[attribut] not in vus:
vus.append(ligne[attribut])
resultat.append(ligne)
return resultat

Avant de traiter des données, il est important de vérifier leur cohérence : valeurs manquantes, types incorrects, valeurs aberrantes.

def valeurs_manquantes(table, attribut):
"""Renvoie les indices des lignes où l'attribut est vide."""
indices = []
for i, ligne in enumerate(table):
if attribut not in ligne or ligne[attribut] == "":
indices.append(i)
return indices
def valeurs_aberrantes(table, attribut, val_min, val_max):
"""Renvoie les lignes où l'attribut est hors de l'intervalle attendu."""
return [ligne for ligne in table if ligne[attribut] < val_min or ligne[attribut] > val_max]
# Exemple : âges aberrants (hors [10, 20])
aberrants = valeurs_aberrantes(table, "age", 10, 20)
def verifier_entiers(table, attribut):
"""Vérifie que toutes les valeurs d'un attribut sont des entiers."""
for i, ligne in enumerate(table):
try:
int(ligne[attribut])
except (ValueError, TypeError):
print(f"Ligne {i} : '{ligne[attribut]}' n'est pas un entier")

L'agrégation consiste à calculer une valeur résumant une colonne entière.

table = [
{"nom": "Dupont", "note": 15},
{"nom": "Martin", "note": 12},
{"nom": "Durand", "note": 18},
{"nom": "Petit", "note": 9}
]
notes = [e["note"] for e in table]
print(f"Nombre : {len(notes)}") # 4
print(f"Somme : {sum(notes)}") # 54
print(f"Moyenne : {sum(notes)/len(notes)}") # 13.5
print(f"Min : {min(notes)}") # 9
print(f"Max : {max(notes)}") # 18

OpérationDescriptionSyntaxe Python
ProjectionGarder certaines colonnesCompréhension avec sélection de clés
FiltrageGarder certaines lignes[e for e in table if condition]
TriOrdonner les lignessorted(table, key=lambda e: e["col"])
DoublonsRepérer les valeurs en doubleParcours avec ensemble des valeurs vues
CohérenceVérifier les donnéesTests sur les valeurs manquantes, types, bornes
AgrégationRésumer une colonnesum(), min(), max(), len()