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)

Défi 1 défi

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))
Défi 2 défi

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)
Défi 3 défi

Pourquoi reduce(lambda acc,x: acc+[x], liste, []) est-il un mauvais usage de reduce ?

Voir la réponse
Complexité quadratique (chaque concaténation recopie toute la liste) pour ne faire qu'une copie — list(liste) suffit, en linéaire et bien plus lisible.