Séance 2 — map, filter, reduce, lambda
1. La syntaxe lambda
Une lambda est une fonction anonyme réduite à une unique expression.
carre = lambda x: x * x
print(carre(5)) # 25
eleves = [("Alice", 14), ("Bob", 17), ("Chloé", 9)]
eleves_tries = sorted(eleves, key=lambda e: e[1])
2. Exercice 1 — Tri personnalisé
eleves = [
{"nom": "Alice", "note": 14, "absences": 2},
{"nom": "Bob", "note": 17, "absences": 5},
{"nom": "Chloé", "note": 9, "absences": 0},
]
a) Trie par note croissante. b) Par note décroissante. c) Par absences croissantes.
Voir la réponse
sorted(eleves, key=lambda e: e["note"])
sorted(eleves, key=lambda e: e["note"], reverse=True)
sorted(eleves, key=lambda e: e["absences"])
3. Exercice 2 — Le chef d'orchestre (reduce, fait main)
Écris produit_liste(liste) qui calcule le produit de tous les éléments avec une boucle et un accumulateur.
Voir la réponse
def produit_liste(liste):
acc = 1
for x in liste:
acc = acc * x
return acc
print(produit_liste([1, 2, 3, 4, 5])) # 120
4. functools.reduce
reduce(fonction, iterable, valeur_initiale) agrège tous les éléments en une seule valeur.
from functools import reduce
nombres = [1, 2, 3, 4, 5]
produit = reduce(lambda acc, x: acc * x, nombres, 1)
print(produit) # 120
c) Réécris produit_liste avec reduce. d) Trouve le plus grand élément d'une liste avec reduce (sans max()).
Voir la réponse
produit = reduce(lambda acc, x: acc * x, [1,2,3,4,5], 1)
maximum = reduce(lambda acc, x: x if x > acc else acc, nombres, nombres[0])
5. Exercice 3 — Combiner filter, map, reduce
Calcule la somme des multiples de 3 ou 5 en dessous de 1000.
Voir la réponse
from functools import reduce
multiples = filter(lambda n: n % 3 == 0 or n % 5 == 0, range(1000))
somme = reduce(lambda acc, x: acc + x, multiples, 0)
print(somme) # 233168
6. Exercice 4 — Statistiques d'une classe
notes = [8, 12, 15, 6, 19, 10, 14, 3, 17, 11]
a) Moyenne avec reduce. b) Nombre d'admis (≥10) avec filter. c) Note max avec reduce. d) Compare avec sum()/len()/max().
Voir la réponse
somme = reduce(lambda acc, x: acc + x, notes, 0)
moyenne = somme / len(notes)
admis = list(filter(lambda n: n >= 10, notes))
note_max = reduce(lambda acc, x: x if x > acc else acc, notes, notes[0])
sum() et max() sont des cas particuliers de reduce, spécialisés et optimisés.
Exercices défis (bonus)
Implémente ta propre version récursive de reduce.
Voir la réponse
def mon_reduce(fonction, iterable, valeur_initiale):
iterable = list(iterable)
if not iterable:
return valeur_initiale
premier, *reste = iterable
return mon_reduce(fonction, reste, fonction(valeur_initiale, premier))
Somme des carrés des nombres pairs d'une liste, en une expression filter/map/reduce.
Voir la réponse
somme = reduce(lambda acc, x: acc + x,
map(lambda x: x**2, filter(lambda x: x % 2 == 0, liste)), 0)
Pourquoi reduce(lambda acc,x: acc+[x], liste, []) est-il un mauvais usage de reduce ?