Cours Python : Les fonctions Lambda (fonctions anonymes)
? Objectif du cours : Maîtriser les fonctions lambda en Python, ces fonctions "express" qui permettent d'écrire du code plus concis et élégant.
Partie 1 : Introduction aux fonctions Lambda
1.1 Qu'est-ce qu'une fonction lambda ?
Une fonction lambda est une fonction anonyme (sans nom) définie sur une seule ligne. C'est comme une fonction classique, mais en version "express" !
? Analogie :
- Fonction classique = Un repas préparé avec une recette détaillée (plus long à écrire)
- Fonction lambda = Un pain avec chocolat préparé rapidement (simple et efficace pour les petites tâches)
Tableau comparatif : Fonction classique vs Lambda
| Caractéristique |
Fonction classique (def) |
Fonction lambda |
| Syntaxe |
def nom(params): return résultat |
lambda params: résultat |
| Nom |
A un nom (obligatoire) |
Anonyme (pas de nom) |
| Longueur |
Plusieurs lignes possibles |
Une seule ligne obligatoire |
| Complexité |
Peut contenir des boucles, conditions complexes |
Expression simple uniquement |
| Usage typique |
Fonctions réutilisables complexes |
Fonctions jetables pour filter, map, sort |
1.2 Syntaxe de base
? Exemple 1 : Premières lambdas
# Syntaxe générale : lambda paramètres: expression
# Lambda à 1 paramètre
carre = lambda x: x ** 2
print(carre(5)) # 25
# Lambda à 2 paramètres
addition = lambda a, b: a + b
print(addition(10, 5)) # 15
# Lambda à 3 paramètres
volume = lambda l, L, h: l * L * h
print(volume(2, 3, 4)) # 24
# Lambda sans paramètre
bonjour = lambda: "PandaCodeur"
print(bonjour()) # PandaCodeur
✅ À retenir :
- Le mot-clé
lambda remplace def
- Pas de parenthèses pour les paramètres (juste après lambda)
- Pas de
return explicite - l'expression est automatiquement retournée
- Une seule expression (pas d'instructions complexes)
Partie 2 : Lambda vs Fonction classique
2.1 Même fonction, deux écritures
? Exemple 2 : Comparaison directe
# VERSION CLASSIQUE (avec def)
def multiplier_def(a, b):
return a * b
# VERSION LAMBDA (anonyme)
multiplier_lambda = lambda a, b: a * b
# Les deux s'utilisent de la même façon
print(multiplier_def(3, 4)) # 12
print(multiplier_lambda(3, 4)) # 12
# Vérification : ce sont les mêmes types ?
print(type(multiplier_def)) #
print(type(multiplier_lambda)) #
? Exemple 3 : Conditions dans les lambdas
# Lambda avec condition (opérateur ternaire)
est_pair = lambda x: "pair" if x % 2 == 0 else "impair"
print(est_pair(4)) # pair
print(est_pair(7)) # impair
# Équivalent en fonction classique
def est_pair_classique(x):
if x % 2 == 0:
return "pair"
else:
return "impair"
# Lambda avec conditions multiples
categorie_age = lambda age: "enfant" if age < 12 else "adolescent" if age < 18 else "adulte"
print(categorie_age(8)) # enfant
print(categorie_age(15)) # adolescent
print(categorie_age(25)) # adulte
⚠️ Limitation importante : Les lambdas ne peuvent contenir qu'une
seule expression. Pas de boucles
for, pas de
while, pas d'assignations multiples !
# ❌ Ceci ne fonctionnera PAS :
mauvaise_lambda = lambda x: for i in x: print(i) # SyntaxError
# ✅ Mais on peut utiliser des expressions complexes :
bonne_lambda = lambda x: [i**2 for i in x] # OK (compréhension de liste)
Partie 3 : Les lambdas avec les fonctions intégrées
3.1 Lambda avec filter() - On révise !
? Exemple 4 : filter() + lambda
nombres = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
# Filtrer les nombres pairs
pairs = list(filter(lambda x: x % 2 == 0, nombres))
print(pairs) # [2, 4, 6, 8, 10]
# Filtrer les nombres > 5
grands = list(filter(lambda x: x > 5, nombres))
print(grands) # [6, 7, 8, 9, 10]
# Application sur des chaînes
mots = ["python", "java", "javascript", "php", "ruby"]
mots_courts = list(filter(lambda mot: len(mot) <= 4, mots))
print(mots_courts) # ['java', 'php', 'ruby']
3.2 Lambda avec map() - Transformer des données
? map() : Applique une fonction à chaque élément d'une liste et retourne une nouvelle liste avec les résultats.
? Exemple 5 : map() + lambda
nombres = [1, 2, 3, 4, 5]
# Mettre chaque nombre au carré
carres = list(map(lambda x: x ** 2, nombres))
print(carres) # [1, 4, 9, 16, 25]
# Convertir en degrés Celsius -> Fahrenheit
celsius = [0, 10, 20, 30, 40]
fahrenheit = list(map(lambda c: (c * 9/5) + 32, celsius))
print(fahrenheit) # [32.0, 50.0, 68.0, 86.0, 104.0]
# Travailler avec des chaînes
noms = ["alice", "bob", "charlie"]
noms_majuscules = list(map(lambda nom: nom.upper(), noms))
print(noms_majuscules) # ['ALICE', 'BOB', 'CHARLIE']
# Formater des données
prix_ht = [100, 250, 75, 120]
prix_ttc = list(map(lambda p: f"{p * 1.2:.2f} € TTC", prix_ht))
print(prix_ttc) # ['120.00 € TTC', '300.00 € TTC', '90.00 € TTC', '144.00 € TTC']
3.3 Lambda avec sorted() - Tri personnalisé
? Exemple 6 : sorted() + lambda
# Tri de tuples par le deuxième élément
etudiants = [("Alice", 22), ("Bob", 19), ("Charlie", 25), ("Diana", 21)]
tries_par_age = sorted(etudiants, key=lambda etudiant: etudiant[1])
print("Tri par âge:", tries_par_age)
# [('Bob', 19), ('Diana', 21), ('Alice', 22), ('Charlie', 25)]
# Tri de dictionnaires
personnes = [
{"nom": "Martin", "age": 45},
{"nom": "Bernard", "age": 32},
{"nom": "Petit", "age": 28},
{"nom": "Durand", "age": 51}
]
tries_par_nom = sorted(personnes, key=lambda p: p["nom"])
print("\nTri par nom:")
for p in tries_par_nom:
print(f" {p['nom']} ({p['age']} ans)")
tries_par_age = sorted(personnes, key=lambda p: p["age"], reverse=True)
print("\nTri par âge (décroissant):")
for p in tries_par_age:
print(f" {p['nom']} ({p['age']} ans)")
# Tri de chaînes par longueur
mots = ["python", "java", "javascript", "c", "ruby", "typescript"]
tries_par_longueur = sorted(mots, key=lambda mot: len(mot))
print("\nMots triés par longueur:", tries_par_longueur)
# ['c', 'java', 'ruby', 'python', 'javascript', 'typescript']
3.4 Lambda avec max() et min() - Recherche personnalisée
? Exemple 7 : max()/min() + lambda
# Trouver l'étudiant le plus âgé
etudiants = [("Alice", 22), ("Bob", 19), ("Charlie", 25), ("Diana", 21)]
plus_age = max(etudiants, key=lambda e: e[1])
plus_jeune = min(etudiants, key=lambda e: e[1])
print(f"Plus âgé: {plus_age[0]} ({plus_age[1]} ans)")
print(f"Plus jeune: {plus_jeune[0]} ({plus_jeune[1]} ans)")
# Trouver le mot le plus long
mots = ["python", "java", "javascript", "c", "typescript"]
mot_long = max(mots, key=lambda m: len(m))
mot_court = min(mots, key=lambda m: len(m))
print(f"\nMot le plus long: {mot_long} ({len(mot_long)} lettres)")
print(f"Mot le plus court: {mot_court} ({len(mot_court)} lettres)")
# Dans un dictionnaire
ventes = {"janvier": 4500, "février": 5200, "mars": 3800, "avril": 6100}
meilleur_mois = max(ventes.items(), key=lambda m: m[1])
pire_mois = min(ventes.items(), key=lambda m: m[1])
print(f"\nMeilleur mois: {meilleur_mois[0]} ({meilleur_mois[1]}€)")
print(f"Pire mois: {pire_mois[0]} ({pire_mois[1]}€)")
Partie 4 : Cas pratiques avancés
4.1 Lambdas avec plusieurs listes
? Exemple 8 : Combiner des listes
notes = [15, 12, 18, 10, 14]
coefficients = [2, 1, 3, 1, 2]
# Calculer les notes pondérées avec map et zip
notes_ponderees = list(map(lambda x: x[0] * x[1], zip(notes, coefficients)))
print("Notes pondérées:", notes_ponderees) # [30, 12, 54, 10, 28]
# Moyenne pondérée
moyenne = sum(notes_ponderees) / sum(coefficients)
print(f"Moyenne pondérée: {moyenne:.2f}") # Moyenne pondérée: 13.33
# Avec 3 listes
noms = ["Alice", "Bob", "Charlie"]
ages = [22, 19, 25]
villes = ["Paris", "Lyon", "Marseille"]
personnes = list(map(lambda a, b, c: f"{a} ({b} ans, {c})", noms, ages, villes))
print("\nPersonnes:", personnes)
# ['Alice (22 ans, Paris)', 'Bob (19 ans, Lyon)', 'Charlie (25 ans, Marseille)']
4.2 Lambdas avec des dictionnaires complexes
? Exemple 9 : Analyser des données
employes = [
{"nom": "Martin", "prenom": "Jean", "service": "IT", "salaire": 45000, "prime": 5000},
{"nom": "Bernard", "prenom": "Marie", "service": "Marketing", "salaire": 38000, "prime": 3000},
{"nom": "Petit", "prenom": "Pierre", "service": "IT", "salaire": 42000, "prime": 4500},
{"nom": "Durand", "prenom": "Sophie", "service": "RH", "salaire": 35000, "prime": 2000},
{"nom": "Leroy", "prenom": "Paul", "service": "IT", "salaire": 48000, "prime": 6000}
]
# 1. Calculer le salaire total (salaire + prime) pour chaque employé
employes_avec_total = list(map(
lambda e: {**e, "total": e["salaire"] + e["prime"]},
employes
))
print("Employés avec salaire total:")
for e in employes_avec_total[:3]: # Afficher les 3 premiers
print(f" {e['prenom']} {e['nom']}: {e['total']}€")
# 2. Filtrer les employés IT avec total > 45000
it_bien_payes = list(filter(
lambda e: e["service"] == "IT" and (e["salaire"] + e["prime"]) > 45000,
employes
))
print("\nIT bien payés (>45000€):")
for e in it_bien_payes:
print(f" {e['prenom']} {e['nom']}: {e['salaire'] + e['prime']}€")
# 3. Trier par salaire total décroissant
tries_par_total = sorted(employes, key=lambda e: e["salaire"] + e["prime"], reverse=True)
print("\nClassement par salaire total:")
for i, e in enumerate(tries_par_total, 1):
total = e["salaire"] + e["prime"]
print(f" {i}. {e['prenom']} {e['nom']}: {total}€")
4.3 Lambdas dans des expressions conditionnelles
? Exemple 10 : Lambdas dynamiques
# Créer des fonctions de calcul selon un choix
def creer_operation(operateur):
if operateur == "+":
return lambda a, b: a + b
elif operateur == "-":
return lambda a, b: a - b
elif operateur == "*":
return lambda a, b: a * b
elif operateur == "/":
return lambda a, b: a / b if b != 0 else "Division par zéro"
else:
return lambda a, b: "Opérateur inconnu"
# Utilisation
addition = creer_operation("+")
print(addition(10, 5)) # 15
multiplication = creer_operation("*")
print(multiplication(10, 5)) # 50
# Lambda qui choisit une lambda selon une condition
calcul_adapte = lambda x: (lambda y: y * 2) if x > 0 else (lambda y: y / 2)
fonction = calcul_adapte(10)
print(fonction(20)) # 40 (car 10 > 0, donc multiplication par 2)
fonction = calcul_adapte(-5)
print(fonction(20)) # 10.0 (car -5 < 0, donc division par 2)
Partie 5 : Exercices pratiques avec corrigés
Exercice 1 : Gestion de notes
etudiants = [
{"nom": "Alice", "notes": [15, 18, 12, 14]},
{"nom": "Bob", "notes": [8, 12, 10, 9]},
{"nom": "Charlie", "notes": [19, 17, 18, 20]},
{"nom": "Diana", "notes": [14, 13, 15, 12]}
]
- Calcule la moyenne de chaque étudiant en utilisant map() et lambda
- Filtre les étudiants qui ont la moyenne (≥ 10)
- Trie les étudiants par moyenne décroissante
- Trouve le meilleur étudiant
Exercice 2 : Panier d'achat
panier = [
{"produit": "pommes", "prix": 2.5, "quantite": 6, "tva": 5.5},
{"produit": "bananes", "prix": 1.8, "quantite": 4, "tva": 5.5},
{"produit": "chocolat", "prix": 3.5, "quantite": 2, "tva": 20},
{"produit": "café", "prix": 8.5, "quantite": 1, "tva": 20},
{"produit": "yaourts", "prix": 1.2, "quantite": 12, "tva": 5.5}
]
- Ajoute un champ "prix_ttc" à chaque produit (prix * (1 + tva/100))
- Calcule le total TTC du panier
- Filtre les produits dont le prix TTC unitaire est > 3€
- Trie les produits par prix TTC décroissant
Exercice 3 : Analyse de texte
phrases = [
"Python est un langage génial",
"Les fonctions lambda sont pratiques",
"Apprendre à programmer est amusant",
"Les listes et dictionnaires sont utiles"
]
- Compte le nombre de mots dans chaque phrase
- Trouve la phrase la plus longue (en nombre de mots)
- Convertit toutes les phrases en majuscules
- Filtre les phrases qui contiennent le mot "lambda"
Solutions
Solution Exercice 1
etudiants = [
{"nom": "Alice", "notes": [15, 18, 12, 14]},
{"nom": "Bob", "notes": [8, 12, 10, 9]},
{"nom": "Charlie", "notes": [19, 17, 18, 20]},
{"nom": "Diana", "notes": [14, 13, 15, 12]}
]
# 1. Calculer les moyennes
etudiants_avec_moyenne = list(map(
lambda e: {**e, "moyenne": sum(e["notes"]) / len(e["notes"])},
etudiants
))
print("1. Étudiants avec leur moyenne:")
for e in etudiants_avec_moyenne:
print(f" {e['nom']}: {e['moyenne']:.2f}")
# 2. Filtrer ceux qui ont la moyenne (≥ 10)
admis = list(filter(lambda e: e["moyenne"] >= 10, etudiants_avec_moyenne))
print("\n2. Étudiants admis:")
for e in admis:
print(f" {e['nom']}: {e['moyenne']:.2f}")
# 3. Trier par moyenne décroissante
classement = sorted(etudiants_avec_moyenne, key=lambda e: e["moyenne"], reverse=True)
print("\n3. Classement:")
for i, e in enumerate(classement, 1):
print(f" {i}. {e['nom']}: {e['moyenne']:.2f}")
# 4. Meilleur étudiant
meilleur = max(etudiants_avec_moyenne, key=lambda e: e["moyenne"])
print(f"\n4. Meilleur étudiant: {meilleur['nom']} avec {meilleur['moyenne']:.2f} de moyenne")
Solution Exercice 2
panier = [
{"produit": "pommes", "prix": 2.5, "quantite": 6, "tva": 5.5},
{"produit": "bananes", "prix": 1.8, "quantite": 4, "tva": 5.5},
{"produit": "chocolat", "prix": 3.5, "quantite": 2, "tva": 20},
{"produit": "café", "prix": 8.5, "quantite": 1, "tva": 20},
{"produit": "yaourts", "prix": 1.2, "quantite": 12, "tva": 5.5}
]
# 1. Ajouter prix TTC
panier_ttc = list(map(
lambda p: {
**p,
"prix_ttc": round(p["prix"] * (1 + p["tva"]/100), 2),
"total_ttc": round(p["prix"] * (1 + p["tva"]/100) * p["quantite"], 2)
},
panier
))
print("1. Panier avec prix TTC:")
for p in panier_ttc:
print(f" {p['produit']}: {p['prix_ttc']}€ (x{p['quantite']} = {p['total_ttc']}€)")
# 2. Total du panier
total_panier = sum(map(lambda p: p["total_ttc"], panier_ttc))
print(f"\n2. Total du panier: {total_panier:.2f}€")
# 3. Produits avec prix TTC unitaire > 3€
produits_chers = list(filter(lambda p: p["prix_ttc"] > 3, panier_ttc))
print("\n3. Produits > 3€:")
for p in produits_chers:
print(f" {p['produit']}: {p['prix_ttc']}€")
# 4. Tri par prix TTC décroissant
panier_trie = sorted(panier_ttc, key=lambda p: p["prix_ttc"], reverse=True)
print("\n4. Produits triés par prix décroissant:")
for p in panier_trie:
print(f" {p['produit']}: {p['prix_ttc']}€")
Solution Exercice 3
phrases = [
"Python est un langage génial",
"Les fonctions lambda sont pratiques",
"Apprendre à programmer est amusant",
"Les listes et dictionnaires sont utiles"
]
# 1. Compter les mots
nombres_mots = list(map(lambda p: len(p.split()), phrases))
print("1. Nombre de mots par phrase:")
for i, (phrase, nb) in enumerate(zip(phrases, nombres_mots)):
print(f" Phrase {i+1}: {nb} mots")
# 2. Phrase la plus longue
phrase_longue = max(phrases, key=lambda p: len(p.split()))
nb_mots = len(phrase_longue.split())
print(f"\n2. Phrase la plus longue ({nb_mots} mots):")
print(f" \"{phrase_longue}\"")
# 3. Convertir en majuscules
phrases_maj = list(map(lambda p: p.upper(), phrases))
print("\n3. Phrases en majuscules:")
for p in phrases_maj:
print(f" {p}")
# 4. Filtrer celles avec "lambda"
phrases_lambda = list(filter(lambda p: "lambda" in p.lower(), phrases))
print("\n4. Phrases contenant 'lambda':")
if phrases_lambda:
for p in phrases_lambda:
print(f" \"{p}\"")
else:
print(" Aucune phrase ne contient le mot 'lambda'")
Bonus : Techniques avancées avec les lambdas
? Exemple Bonus : Fonctions d'ordre supérieur
# Une fonction qui retourne une lambda
def multiplicateur(facteur):
return lambda x: x * facteur
double = multiplicateur(2)
triple = multiplicateur(3)
print(double(10)) # 20
print(triple(10)) # 30
# Composition de fonctions
def compose(f, g):
return lambda x: f(g(x))
carre = lambda x: x ** 2
incremente = lambda x: x + 1
carre_et_incremente = compose(incremente, carre)
incremente_et_carre = compose(carre, incremente)
print(carre_et_incremente(5)) # (5²) + 1 = 26
print(incremente_et_carre(5)) # (5+1)² = 36
# Évaluation paresseuse (lazy evaluation)
def creer_comparateur(seuil):
return lambda x: x > seuil
est_superieur_a_10 = creer_comparateur(10)
est_superieur_a_100 = creer_comparateur(100)
nombres = [5, 15, 25, 105]
print(list(filter(est_superieur_a_10, nombres))) # [15, 25, 105]
print(list(filter(est_superieur_a_100, nombres))) # [105]
? Résumé des points clés à retenir sur les lambdas :
- Syntaxe :
lambda paramètres: expression
- Pas de return : l'expression est automatiquement retournée
- Une seule ligne : idéal pour des fonctions simples et jetables
- Parfait avec :
filter(), map(), sorted(), max(), min()
- À éviter pour : des fonctions complexes avec plusieurs instructions
- Peut être assignée : à une variable pour la réutiliser (mais on perd l'intérêt de l'anonymat)
⚠️ Quand NE PAS utiliser de lambda :
- Fonctions de plus d'une ligne
- Fonctions avec des boucles
- Fonctions complexes avec plusieurs conditions imbriquées
- Quand la lisibilité du code est plus importante que la concision
- Pour des fonctions réutilisées à plusieurs endroits (préférer
def)
? Statistiques d'utilisation :
| Fonction |
Utilisation typique avec lambda |
Fréquence |
| sorted() |
Tri personnalisé avec key= |
⭐⭐⭐⭐⭐ |
| filter() |
Filtrage conditionnel |
⭐⭐⭐⭐ |
| map() |
Transformation de données |
⭐⭐⭐⭐ |
| max()/min() |
Trouver l'élément selon un critère |
⭐⭐⭐ |
✨ Les lambdas sont comme des couteaux suisses : pratiques pour les petites tâches rapides, mais mieux vaut utiliser des outils plus adaptés pour les gros travaux !