28  Extraction et traitement de volumes de données

Beaucoup de programmes passent leur temps à manipuler des collections de données : notes d’élèves, transactions, capteurs, articles… Ce chapitre rassemble les 4 opérations de base qu’on applique à des volumes de données, et montre comment les combiner pour produire des résultats utiles.

28.1 Les 4 opérations de base

Opération Rôle Résultat
Filtrer Garder un sous-ensemble selon un critère Nouvelle collection (éventuellement plus petite)
Transformer Appliquer une fonction à chaque élément Nouvelle collection (même taille)
Agréger Combiner tous les éléments en une valeur unique Une valeur (somme, moyenne, max…)
Grouper Répartir les éléments par catégorie Dictionnaire par catégorie

Vous verrez ces 4 opérations partout : Excel (filtres, formules, pivot), SQL (WHERE, SELECT, SUM, GROUP BY), Pandas… et bien sûr en Python.

Pour toutes les démos, on utilisera le même jeu de données :

etudiants = [
    {"nom": "Alice",   "classe": "A", "note": 14, "age": 20},
    {"nom": "Bob",     "classe": "B", "note":  8, "age": 22},
    {"nom": "Charlie", "classe": "A", "note": 17, "age": 19},
    {"nom": "Diana",   "classe": "B", "note":  9, "age": 21},
    {"nom": "Eve",     "classe": "A", "note": 15, "age": 20},
    {"nom": "Frank",   "classe": "B", "note": 11, "age": 23},
    {"nom": "Grace",   "classe": "A", "note": 18, "age": 19},
]

28.2 Filtrer une collection

Filtrer = conserver uniquement les éléments qui vérifient une condition.

Avec une boucle explicite

etudiants = [
    {"nom": "Alice",   "classe": "A", "note": 14, "age": 20},
    {"nom": "Bob",     "classe": "B", "note":  8, "age": 22},
    {"nom": "Charlie", "classe": "A", "note": 17, "age": 19},
    {"nom": "Diana",   "classe": "B", "note":  9, "age": 21},
    {"nom": "Eve",     "classe": "A", "note": 15, "age": 20},
    {"nom": "Frank",   "classe": "B", "note": 11, "age": 23},
    {"nom": "Grace",   "classe": "A", "note": 18, "age": 19},
]

# Filtrer : les étudiants ayant 10 ou plus
admis = []
for e in etudiants:
    if e["note"] >= 10:
        admis.append(e)

print(f"{len(admis)} étudiants admis")
for e in admis:
    print(f"  {e['nom']} : {e['note']}")
5 étudiants admis
  Alice : 14
  Charlie : 17
  Eve : 15
  Frank : 11
  Grace : 18

Avec une compréhension de liste (aperçu)

La même chose en une ligne avec une compréhension de liste (vue en Partie 3) :

etudiants = [
    {"nom": "Alice",   "classe": "A", "note": 14, "age": 20},
    {"nom": "Bob",     "classe": "B", "note":  8, "age": 22},
    {"nom": "Charlie", "classe": "A", "note": 17, "age": 19},
    {"nom": "Diana",   "classe": "B", "note":  9, "age": 21},
    {"nom": "Eve",     "classe": "A", "note": 15, "age": 20},
    {"nom": "Frank",   "classe": "B", "note": 11, "age": 23},
    {"nom": "Grace",   "classe": "A", "note": 18, "age": 19},
]

admis = [e for e in etudiants if e["note"] >= 10]
print(f"{len(admis)} étudiants admis")
5 étudiants admis

C’est plus court, plus lisible, et plus rapide. À ce stade, acceptez la syntaxe — la partie 3 la développera complètement.

Filtrage avec la fonction filter()

Python propose aussi la fonction native filter(). Moins utilisée aujourd’hui au profit des compréhensions, mais à reconnaître pour le TOSA.

etudiants = [
    {"nom": "Alice", "note": 14},
    {"nom": "Bob",   "note": 8},
    {"nom": "Eve",   "note": 15},
]

admis = list(filter(lambda e: e["note"] >= 10, etudiants))
print(admis)
[{'nom': 'Alice', 'note': 14}, {'nom': 'Eve', 'note': 15}]

filter(fonction, iterable) renvoie un itérateur — d’où le list(...) pour voir le résultat.

28.3 Transformer une collection

Transformer = appliquer une fonction à chaque élément pour produire une nouvelle collection.

Avec une boucle

notes = [12, 15, 9, 17, 11]

# Convertir en note sur 100
notes_100 = []
for n in notes:
    notes_100.append(n * 5)

print(notes_100)
[60, 75, 45, 85, 55]

Avec une compréhension

notes = [12, 15, 9, 17, 11]

notes_100 = [n * 5 for n in notes]
print(notes_100)
[60, 75, 45, 85, 55]

Extraire un champ d’une liste de dicts (cas très fréquent)

etudiants = [
    {"nom": "Alice", "note": 14},
    {"nom": "Bob",   "note": 8},
    {"nom": "Eve",   "note": 15},
]

# Ne garder que les noms
noms = [e["nom"] for e in etudiants]
print(noms)

# Ne garder que les notes
notes = [e["note"] for e in etudiants]
print(notes)
['Alice', 'Bob', 'Eve']
[14, 8, 15]

Avec la fonction map()

Comme pour filter(), Python propose map(fonction, iterable). Moins utilisée aujourd’hui.

notes = [12, 15, 9, 17]

notes_100 = list(map(lambda n: n * 5, notes))
print(notes_100)
[60, 75, 45, 85]
map / filter vs compréhensions

Les compréhensions sont aujourd’hui préférées parce que :

  • Plus lisibles : [n * 2 for n in notes] se lit mieux que list(map(lambda n: n * 2, notes)).
  • Elles combinent map et filter en une expression : [n * 2 for n in notes if n > 0].

map et filter restent utiles dans du code fonctionnel ou avec des fonctions existantes :

# Utile quand on a déjà la fonction à appliquer
notes = ["12", "15", "9"]
entiers = list(map(int, notes))    # convertit chaque str en int
print(entiers)
[12, 15, 9]

28.4 Agréger une collection

Agréger = combiner tous les éléments en une valeur unique (somme, moyenne, max…).

Fonctions natives

Les agrégations simples ont leur raccourci natif :

notes = [12, 15, 9, 17, 11, 14]

print("Somme    :", sum(notes))
print("Moyenne  :", sum(notes) / len(notes))
print("Minimum  :", min(notes))
print("Maximum  :", max(notes))
print("Longueur :", len(notes))
Somme    : 78
Moyenne  : 13.0
Minimum  : 9
Maximum  : 17
Longueur : 6

Comptage sous condition

Pour compter les éléments vérifiant une condition :

notes = [12, 15, 9, 17, 11, 8, 14]

# Avec une boucle
admis = 0
for n in notes:
    if n >= 10:
        admis += 1
print(f"{admis} notes >= 10")

# Avec sum (astuce : True vaut 1, False vaut 0 en Python)
admis = sum(1 for n in notes if n >= 10)
print(f"{admis} notes >= 10")

# Encore plus court
admis = sum(n >= 10 for n in notes)       # somme des booléens !
print(f"{admis} notes >= 10")
5 notes >= 10
5 notes >= 10
5 notes >= 10

Agréger avec une clé

min et max acceptent key= — utile pour trouver l’élément correspondant au min/max d’un critère.

etudiants = [
    {"nom": "Alice",   "note": 14},
    {"nom": "Bob",     "note":  8},
    {"nom": "Charlie", "note": 17},
]

# Le meilleur étudiant (celui avec la note max)
meilleur = max(etudiants, key=lambda e: e["note"])
print("Meilleur :", meilleur)

# Le plus faible
faible = min(etudiants, key=lambda e: e["note"])
print("Plus faible :", faible)
Meilleur : {'nom': 'Charlie', 'note': 17}
Plus faible : {'nom': 'Bob', 'note': 8}

28.5 Grouper par catégorie

Grouper = répartir les éléments dans un dictionnaire selon une clé catégorielle.

Manuellement

etudiants = [
    {"nom": "Alice",   "classe": "A", "note": 14},
    {"nom": "Bob",     "classe": "B", "note":  8},
    {"nom": "Charlie", "classe": "A", "note": 17},
    {"nom": "Diana",   "classe": "B", "note":  9},
    {"nom": "Eve",     "classe": "A", "note": 15},
]

par_classe = {}
for e in etudiants:
    c = e["classe"]
    if c not in par_classe:
        par_classe[c] = []
    par_classe[c].append(e)

for classe, liste in par_classe.items():
    print(f"Classe {classe} : {len(liste)} étudiants")
    for e in liste:
        print(f"  - {e['nom']} ({e['note']})")
Classe A : 3 étudiants
  - Alice (14)
  - Charlie (17)
  - Eve (15)
Classe B : 2 étudiants
  - Bob (8)
  - Diana (9)

Avec dict.setdefault

On peut simplifier avec setdefault(clé, défaut) — renvoie la valeur existante, ou crée avec le défaut.

etudiants = [
    {"nom": "Alice",   "classe": "A", "note": 14},
    {"nom": "Bob",     "classe": "B", "note":  8},
    {"nom": "Charlie", "classe": "A", "note": 17},
]

par_classe = {}
for e in etudiants:
    par_classe.setdefault(e["classe"], []).append(e)

print(par_classe)
{'A': [{'nom': 'Alice', 'classe': 'A', 'note': 14}, {'nom': 'Charlie', 'classe': 'A', 'note': 17}], 'B': [{'nom': 'Bob', 'classe': 'B', 'note': 8}]}

Avec collections.defaultdict

La solution la plus élégante utilise un defaultdict :

from collections import defaultdict

etudiants = [
    {"nom": "Alice",   "classe": "A", "note": 14},
    {"nom": "Bob",     "classe": "B", "note":  8},
    {"nom": "Charlie", "classe": "A", "note": 17},
]

par_classe = defaultdict(list)         # valeur par défaut = liste vide
for e in etudiants:
    par_classe[e["classe"]].append(e)

# Accès aux groupes
print(dict(par_classe))
{'A': [{'nom': 'Alice', 'classe': 'A', 'note': 14}, {'nom': 'Charlie', 'classe': 'A', 'note': 17}], 'B': [{'nom': 'Bob', 'classe': 'B', 'note': 8}]}

defaultdict(list) crée automatiquement une liste vide la première fois qu’on accède à une clé nouvelle. Pas besoin de if ... not in.

Agréger par catégorie

Une fois groupé, on peut agréger chaque groupe :

from collections import defaultdict

etudiants = [
    {"nom": "Alice",   "classe": "A", "note": 14},
    {"nom": "Bob",     "classe": "B", "note":  8},
    {"nom": "Charlie", "classe": "A", "note": 17},
    {"nom": "Diana",   "classe": "B", "note":  9},
    {"nom": "Eve",     "classe": "A", "note": 15},
]

# Grouper + calculer la moyenne par classe
notes_par_classe = defaultdict(list)
for e in etudiants:
    notes_par_classe[e["classe"]].append(e["note"])

for classe, notes in notes_par_classe.items():
    moyenne = sum(notes) / len(notes)
    print(f"Classe {classe} : moyenne = {moyenne:.1f}")
Classe A : moyenne = 15.3
Classe B : moyenne = 8.5

28.6 Combiner filtrer / transformer / agréger

La vraie puissance vient de la combinaison de ces opérations. Exemple concret : moyenne des notes des étudiants de la classe A qui ont au moins 10.

Version 1 — en trois étapes séparées

etudiants = [
    {"nom": "Alice",   "classe": "A", "note": 14},
    {"nom": "Bob",     "classe": "B", "note":  8},
    {"nom": "Charlie", "classe": "A", "note": 17},
    {"nom": "Diana",   "classe": "B", "note":  9},
    {"nom": "Eve",     "classe": "A", "note": 15},
    {"nom": "Grace",   "classe": "A", "note":  8},    # pas admise
]

# 1. Filtrer : classe A et note >= 10
filtres = []
for e in etudiants:
    if e["classe"] == "A" and e["note"] >= 10:
        filtres.append(e)

# 2. Transformer : ne garder que les notes
notes = [e["note"] for e in filtres]

# 3. Agréger : moyenne
if notes:
    moyenne = sum(notes) / len(notes)
    print(f"Moyenne classe A (admis) : {moyenne:.2f}")
Moyenne classe A (admis) : 15.33

Version 2 — en une compréhension

etudiants = [
    {"nom": "Alice",   "classe": "A", "note": 14},
    {"nom": "Bob",     "classe": "B", "note":  8},
    {"nom": "Charlie", "classe": "A", "note": 17},
    {"nom": "Diana",   "classe": "B", "note":  9},
    {"nom": "Eve",     "classe": "A", "note": 15},
    {"nom": "Grace",   "classe": "A", "note":  8},
]

# Filtrer et extraire les notes en une ligne
notes = [e["note"] for e in etudiants if e["classe"] == "A" and e["note"] >= 10]

# Puis agréger
if notes:
    moyenne = sum(notes) / len(notes)
    print(f"Moyenne classe A (admis) : {moyenne:.2f}")
Moyenne classe A (admis) : 15.33

Les compréhensions et leurs combinaisons sont le sujet central de la Partie 3. À ce stade, mémorisez le principe : filter-map-reduce est une chaîne naturelle qui s’exprime très bien en Python.

28.7 Lire des données depuis l’entrée standard

Dans beaucoup de scripts, les données viennent de l’utilisateur, d’un fichier, ou de l’entrée standard. Au niveau Opérationnel, on se concentre sur input().

Saisie d’une liste

# Saisir plusieurs valeurs séparées par des espaces
ligne = input("Entrez vos notes (séparées par des espaces) : ")
notes = [int(x) for x in ligne.split()]
print("Moyenne :", sum(notes) / len(notes))

Saisie interactive jusqu’à un marqueur de fin

# Saisir des notes une par une, s'arrêter à chaîne vide
notes = []
while True:
    saisie = input("Note (vide pour arrêter) : ").strip()
    if not saisie:
        break
    notes.append(int(saisie))

print(f"{len(notes)} notes saisies, moyenne : {sum(notes)/len(notes):.2f}")

Saisie d’un dict structuré

# Créer une fiche personne interactive
personne = {}
personne["nom"] = input("Nom : ").strip()
personne["age"] = int(input("Âge : "))
personne["ville"] = input("Ville : ").strip()
print(personne)

🧩 Quiz 9.1 — Extraction de données

Question 1

Que renvoie ce code ?

notes = [12, 15, 9, 17, 11]
resultat = [n * 2 for n in notes if n >= 10]
print(resultat)
  1. [24, 30, 34, 22]
  2. [24, 30, 18, 34, 22]
  3. [12, 15, 17, 11]
  4. Une erreur

a) [24, 30, 34, 22] — on filtre (>= 10) puis on transforme (* 2). Le 9 est exclu.

notes = [12, 15, 9, 17, 11]
print([n * 2 for n in notes if n >= 10])
[24, 30, 34, 22]

Question 2

Que renvoie sum(n > 10 for n in [5, 15, 20, 8]) ?

  1. 43
  2. 2
  3. 35
  4. Une erreur

b) 2n > 10 renvoie True (= 1) ou False (= 0). La somme des booléens compte les éléments vérifiant la condition. Ici : 15 > 10 et 20 > 10 → 2.

print(sum(n > 10 for n in [5, 15, 20, 8]))
2

Question 3

Quelle fonction renvoie l’élément maximum selon un critère ?

  1. max(liste, reverse=True)
  2. max(liste, key=...)
  3. sorted(liste)[-1]
  4. max(liste).sort()

b) max(liste, key=...) — le paramètre key sert à spécifier le critère de comparaison. Très utile pour des listes d’objets complexes.

etudiants = [{"nom": "Alice", "note": 14}, {"nom": "Bob", "note": 17}]
print(max(etudiants, key=lambda e: e["note"]))
{'nom': 'Bob', 'note': 17}

Question 4

Quelle structure est la plus adaptée pour grouper des données par catégorie ?

  1. list
  2. tuple
  3. set
  4. dict (ou defaultdict)

d) dict — chaque catégorie est une clé, chaque valeur est la liste des éléments. defaultdict(list) simplifie la création automatique de listes vides.

from collections import defaultdict
groupes = defaultdict(list)
for x in [("A", 1), ("B", 2), ("A", 3)]:
    groupes[x[0]].append(x[1])
print(dict(groupes))
{'A': [1, 3], 'B': [2]}

Question 5

Que renvoie ce code ?

etudiants = [{"nom": "A", "note": 12}, {"nom": "B", "note": 18}]
noms = [e["nom"] for e in etudiants]
print(noms)
  1. ["A", "B"]
  2. ["A", "B", 12, 18]
  3. {"A", "B"}
  4. Une erreur

a) ["A", "B"] — la compréhension extrait le champ "nom" de chaque dict. Pattern très courant.

etudiants = [{"nom": "A", "note": 12}, {"nom": "B", "note": 18}]
print([e["nom"] for e in etudiants])
['A', 'B']

Question 6

Quelle est la différence entre filter() et une compréhension [x for x in l if ...] ?

  1. filter est plus rapide
  2. filter renvoie un itérateur, la compréhension renvoie une liste
  3. filter ne fonctionne qu’avec des nombres
  4. Il n’y a pas de différence

b) filter renvoie un itérateur — il faut list(...) pour obtenir une vraie liste. La compréhension renvoie directement une liste.

# filter renvoie un itérateur
r = filter(lambda n: n > 0, [-1, 2, 3])
print(type(r))
print(list(r))

# compréhension renvoie une liste
r = [n for n in [-1, 2, 3] if n > 0]
print(type(r))
print(r)
<class 'filter'>
[2, 3]
<class 'list'>
[2, 3]

✏️ Exercice 9.1 — Filtrer et compter

À partir du jeu de données initial, comptez combien d’étudiants :

  1. Ont la moyenne (note ≥ 10).
  2. Sont dans la classe A.
  3. Ont la moyenne ET sont dans la classe B.
etudiants = [
    {"nom": "Alice",   "classe": "A", "note": 14},
    {"nom": "Bob",     "classe": "B", "note":  8},
    {"nom": "Charlie", "classe": "A", "note": 17},
    {"nom": "Diana",   "classe": "B", "note":  9},
    {"nom": "Eve",     "classe": "A", "note": 15},
    {"nom": "Frank",   "classe": "B", "note": 11},
    {"nom": "Grace",   "classe": "A", "note": 18},
]

# 1. Ayant la moyenne
...

# 2. Dans la classe A
...

# 3. Moyenne ET classe B
...
etudiants = [
    {"nom": "Alice",   "classe": "A", "note": 14},
    {"nom": "Bob",     "classe": "B", "note":  8},
    {"nom": "Charlie", "classe": "A", "note": 17},
    {"nom": "Diana",   "classe": "B", "note":  9},
    {"nom": "Eve",     "classe": "A", "note": 15},
    {"nom": "Frank",   "classe": "B", "note": 11},
    {"nom": "Grace",   "classe": "A", "note": 18},
]

# 1. Admis
admis = sum(e["note"] >= 10 for e in etudiants)
print("Admis :", admis)

# 2. Classe A
classe_a = sum(e["classe"] == "A" for e in etudiants)
print("Classe A :", classe_a)

# 3. Admis ET classe B
admis_b = sum(e["note"] >= 10 and e["classe"] == "B" for e in etudiants)
print("Admis en B :", admis_b)
Admis : 5
Classe A : 4
Admis en B : 1

✏️ Exercice 9.2 — Transformation d’une liste

Soit la liste mots = ["Alice", " BOB ", " charlie", "DIANA"]. Produisez une nouvelle liste contenant ces mots nettoyés (sans espaces de début/fin) et normalisés (première lettre en majuscule, reste en minuscule).

Exemple de résultat : ["Alice", "Bob", "Charlie", "Diana"].

mots = ["Alice", " BOB ", "   charlie", "DIANA"]

# Nettoyer et normaliser
...
mots = ["Alice", " BOB ", "   charlie", "DIANA"]

# Version boucle
normalises = []
for m in mots:
    normalises.append(m.strip().capitalize())
print(normalises)

# Version compréhension (plus idiomatique)
normalises = [m.strip().capitalize() for m in mots]
print(normalises)
['Alice', 'Bob', 'Charlie', 'Diana']
['Alice', 'Bob', 'Charlie', 'Diana']

.capitalize() met la première lettre en majuscule et le reste en minuscule — exactement ce qu’il faut ici.


✏️ Exercice 9.3 — Agréger par catégorie

À partir du jeu de données des étudiants, produisez un dictionnaire qui associe chaque classe à :

  • Le nombre d’étudiants de la classe.
  • La moyenne des notes de la classe.
  • La meilleure note de la classe.
etudiants = [
    {"nom": "Alice",   "classe": "A", "note": 14},
    {"nom": "Bob",     "classe": "B", "note":  8},
    {"nom": "Charlie", "classe": "A", "note": 17},
    {"nom": "Diana",   "classe": "B", "note":  9},
    {"nom": "Eve",     "classe": "A", "note": 15},
    {"nom": "Frank",   "classe": "B", "note": 11},
    {"nom": "Grace",   "classe": "A", "note": 18},
]

# Produire un dict de la forme :
# {"A": {"nb": 4, "moyenne": 16.0, "max": 18}, "B": {...}}
from collections import defaultdict

etudiants = [
    {"nom": "Alice",   "classe": "A", "note": 14},
    {"nom": "Bob",     "classe": "B", "note":  8},
    {"nom": "Charlie", "classe": "A", "note": 17},
    {"nom": "Diana",   "classe": "B", "note":  9},
    {"nom": "Eve",     "classe": "A", "note": 15},
    {"nom": "Frank",   "classe": "B", "note": 11},
    {"nom": "Grace",   "classe": "A", "note": 18},
]

# Étape 1 : grouper les notes par classe
notes_par_classe = defaultdict(list)
for e in etudiants:
    notes_par_classe[e["classe"]].append(e["note"])

# Étape 2 : calculer les agrégats
stats = {}
for classe, notes in notes_par_classe.items():
    stats[classe] = {
        "nb": len(notes),
        "moyenne": round(sum(notes) / len(notes), 2),
        "max": max(notes),
    }

# Affichage
for classe, infos in sorted(stats.items()):
    print(f"Classe {classe} : {infos}")
Classe A : {'nb': 4, 'moyenne': 16.0, 'max': 18}
Classe B : {'nb': 3, 'moyenne': 9.33, 'max': 11}

✏️ Exercice 9.4 — Pipeline complet

Produisez la liste des prénoms des étudiants de la classe A ayant une note strictement supérieure à 15, triés par note décroissante.

etudiants = [
    {"nom": "Alice",   "classe": "A", "note": 14},
    {"nom": "Bob",     "classe": "B", "note":  8},
    {"nom": "Charlie", "classe": "A", "note": 17},
    {"nom": "Diana",   "classe": "B", "note":  9},
    {"nom": "Eve",     "classe": "A", "note": 15},
    {"nom": "Frank",   "classe": "B", "note": 11},
    {"nom": "Grace",   "classe": "A", "note": 18},
]

# Filtrer → trier → extraire
etudiants = [
    {"nom": "Alice",   "classe": "A", "note": 14},
    {"nom": "Bob",     "classe": "B", "note":  8},
    {"nom": "Charlie", "classe": "A", "note": 17},
    {"nom": "Diana",   "classe": "B", "note":  9},
    {"nom": "Eve",     "classe": "A", "note": 15},
    {"nom": "Frank",   "classe": "B", "note": 11},
    {"nom": "Grace",   "classe": "A", "note": 18},
]

# 1. Filtrer
candidats = [e for e in etudiants if e["classe"] == "A" and e["note"] > 15]

# 2. Trier par note décroissante
candidats.sort(key=lambda e: e["note"], reverse=True)

# 3. Extraire les noms
noms = [e["nom"] for e in candidats]

print("Meilleurs de classe A (note > 15) :", noms)
Meilleurs de classe A (note > 15) : ['Grace', 'Charlie']
etudiants = [
    {"nom": "Alice",   "classe": "A", "note": 14},
    {"nom": "Charlie", "classe": "A", "note": 17},
    {"nom": "Eve",     "classe": "A", "note": 15},
    {"nom": "Grace",   "classe": "A", "note": 18},
    {"nom": "Bob",     "classe": "B", "note":  8},
]

noms = [
    e["nom"]
    for e in sorted(etudiants, key=lambda e: e["note"], reverse=True)
    if e["classe"] == "A" and e["note"] > 15
]
print(noms)
['Grace', 'Charlie']

Ces enchaînements sont très fréquents en data. Maîtrisez-les.


À retenir

Points clés du chapitre
  1. 4 opérations fondamentales : filtrer, transformer, agréger, grouper.
  2. Filtrer avec une compréhension : [x for x in liste if cond].
  3. Transformer avec une compréhension : [f(x) for x in liste].
  4. Agréger : sum, min, max, len, sum(True/False) pour compter.
  5. min/max avec key= pour trouver l’élément optimal selon un critère.
  6. Grouper avec defaultdict(list) ou dict.setdefault(k, []).append(...).
  7. Les chaînes filtrer → trier → transformer sont le pain quotidien du traitement de données.
  8. filter / map existent mais les compréhensions sont plus Pythoniques.

← Chapitre précédent : AlgorithmesTP récapitulatif →