Principes des Langages de Programmation Les expressions lambda
John Samuel
CPE Lyon
Année: 2024-2025
Courriel: john.samuel@cpe.fr
La syntaxe générale d’une expression lambda ressemble à ceci :
(lambda (paramètres) => expression)
Ou dans de nombreux langages modernes :
(paramètres) => expression
Ici, les paramètres
sont les entrées, et l’expression
est l’opération effectuée
lorsque la lambda est invoquée.
Voici quelques exemples d’expressions lambda dans différents langages de programmation :
lambda x: x * 2
(x) => x * 2
(x) -> x * 2
(x) => x * 2
->(x) { x * 2 }
# Exemple : additionner deux nombres
addition = lambda x, y: x + y
résultat = addition(3, 4) # Résultat : 7
Voici une décomposition de l’expression lambda :
addition = lambda x, y: x + y
lambda
est le mot-clé qui indique qu’il s’agit d’une expression lambda.x
et y
sont les paramètres de la fonction, séparés par une virgule. Ils
sont définis implicitement comme des variables locales.x + y
est le corps de la fonction, qui est évalué et renvoie la valeur de la somme de
x
et y
.
# Exemple : additionner deux nombres
addition = lambda x, y: x + y
résultat = addition(3, 4) # Résultat : 7
Lorsque vous assignez cette expression lambda à une variable (addition
), vous pouvez
l’appeler comme une fonction régulière en passant les arguments requis (3
et 4
dans votre exemple).
résultat = addition(3, 4)
addition
est appelée avec les arguments 3
et 4
.7
.résultat
.
# Lambda à l'intérieur d'une fonction map
nombres = [1, 2, 3, 4]
carrés = list(map(lambda x: x ** 2, nombres)) # Résultat : [1, 4, 9, 16]
La fonction map
est une fonction intégrée en Python qui applique une fonction à chaque
élément d’une liste (ou d’un autre itérable) et renvoie une nouvelle liste avec les résultats.
Dans cet exemple, une expression lambda est utilisée pour définir une fonction anonyme qui prend un
élément x
en entrée et renvoie son carré (x ** 2
).
map
est la fonction qui applique la fonction lambda à chaque élément de la liste
nombres
.
lambda x: x ** 2
est l’expression lambda qui définit la fonction anonyme. Elle prend un
élément x
en entrée et renvoie son carré.nombres
est la liste qui contient les éléments à traiter.list
est utilisé pour convertir le résultat de map
en une liste. En Python
3, map
renvoie un objet itérable, mais pas une liste.
# Lambda à l'intérieur d'une fonction map
nombres = [1, 2, 3, 4]
carrés = list(map(lambda x: x ** 2, nombres)) # Résultat : [1, 4, 9, 16]
L’exécution de cette ligne de code produit les résultats suivants :
map
itère sur chaque élément de la liste nombres
.x
, la fonction lambda est appelée avec x
comme
argument.x
.carrés
.Le résultat final est une liste contenant les carrés de chaque élément de la liste nombres
.
// Exemple : additionner deux nombres
const addition = (x, y) => x + y;
const résultat = addition(3, 4); // Résultat : 7
// Lambda passée comme argument à la fonction map
const nombres = [1, 2, 3, 4];
const carrés = nombres.map(x => x ** 2); // Résultat : [1, 4, 9, 16]
#include <iostream>
#include <vector>
#include <algorithm>
int main() {
// Exemple : additionner deux nombres
auto addition = [](int x, int y) { return x + y; };
int résultat = addition(3, 4); // Résultat : 7
}
#include <iostream>
#include <vector>
#include <algorithm>
int main() {
// Lambda dans une fonction for_each
std::vector<int> nombres = {1, 2, 3, 4};
std::for_each(nombres.begin(), nombres.end(), [](int &n) { n *= n; });
for (int n : nombres) {
std::cout << n << " "; // Résultat : 1 4 9 16
}
}
Une expression lambda peut être assignée à une variable, ce qui permet de la réutiliser comme une fonction ordinaire.
Exemple : Additionner deux nombres
# Définition de la lambda
addition = lambda x, y: x + y
# Utilisation de la lambda
résultat = addition(3, 4)
print(résultat) # Output : 7
Les lambdas sont souvent utilisées comme arguments pour d’autres fonctions, notamment dans des fonctions de rappel (callbacks) ou des méthodes qui prennent une fonction en paramètre.
Un callback est une fonction qui est passée en argument à une autre fonction, afin d’être appelée plus tard par cette dernière. En d’autres termes, un callback est une fonction qui est “appelée en retour” par une autre fonction.
Exemple : callback
def appel_fonction(callback, param):
result = callback(param)
print(f"Le résultat de la fonction est : {result}")
# Définition d'une fonction lambda comme callback
callback = lambda x: x ** 2
# Appel de la fonction avec le callback
appel_fonction(callback, 5)
Exemple : callback
Dans cet exemple, la fonction appel_fonction
prend deux paramètres : callback
et param
. Le paramètre callback
est une fonction qui sera appelée avec le paramètre param
. La fonction lambda est définie comme un callback qui prend un paramètre x
et renvoie son carré.
Lorsque nous appelons la fonction appel_fonction
avec le callback et le paramètre 5
, la fonction lambda est appelée avec le paramètre 5
et le résultat est imprimé.
Le résultat de l’exécution de ce code sera :
Le résultat de la fonction est : 25
Cet exemple montre comment utiliser une fonction lambda comme callback en Python. La fonction lambda est définie à la volée et peut être utilisée comme une fonction normale, mais elle est anonyme et ne peut pas être appelée directement.
Il est important de noter que les callbacks peuvent être utilisés pour de nombreuses choses, comme la gestion des événements, la création de fonctions de rappel, etc. Les callbacks sont très utiles en programmation fonctionnelle et sont utilisés dans de nombreux frameworks et bibliothèques Python.
Les lambdas sont souvent utilisées comme arguments pour d’autres fonctions, notamment dans des fonctions de rappel (callbacks) ou des méthodes qui prennent une fonction en paramètre.
Exemple : Utilisation avec map
# Liste de nombres
nombres = [1, 2, 3, 4]
# Utilisation de lambda avec map pour calculer les carrés
carrés = list(map(lambda x: x ** 2, nombres))
print(carrés) # Output : [1, 4, 9, 16]
Exemple : Utilisation avec filter
# Liste de nombres
nombres = [1, 2, 3, 4, 5, 6]
# Utilisation de lambda avec filter pour sélectionner les nombres pairs
pairs = list(filter(lambda x: x % 2 == 0, nombres))
print(pairs) # Output : [2, 4, 6]
Exemple : Utilisation avec filter
filter
prend deux arguments :
True
ou False
pour chaque élément de la liste.Dans ce cas, la fonction utilisée est une expression lambda :
Cette lambda prend un seul paramètre x
(qui représente un élément de la liste) et renvoie True
si x
est pair, c’est-à-dire lorsque x % 2 == 0
.
Exemple : Utilisation avec filter
%
(modulo) donne le reste d’une division. Si le reste est 0
(c’est-à-dire x % 2 == 0
), cela signifie que x
est pair.filter
applique cette lambda à chaque élément de la liste. Si la lambda renvoie True
, l’élément est conservé dans le résultat ; sinon, il est ignoré.1 % 2 == 1
→ False
, donc 1
est ignoré.2 % 2 == 0
→ True
, donc 2
est conservé.3 % 2 == 1
→ False
, donc 3
est ignoré.4 % 2 == 0
→ True
, donc 4
est conservé.5 % 2 == 1
→ False
, donc 5
est ignoré.6 % 2 == 0
→ True
, donc 6
est conservé.Une fonction peut retourner une expression lambda, ce qui permet de créer des fonctions dynamiques. Cela est particulièrement utile pour créer des fonctions personnalisées à la volée.
Exemple : Création d’un multiplicateur
def créer_multiplicateur(n):
return lambda x: x * n
Exemple : Création d’un multiplicateur
# Création d'une lambda qui multiplie par 2
doubler = créer_multiplicateur(2)
print(doubler(5)) # Output : 10
# Création d'une lambda qui multiplie par 3
tripler = créer_multiplicateur(3)
print(tripler(5)) # Output : 15
Les expressions lambda sont souvent utilisées pour effectuer des opérations sur des collections, telles que le tri, la transformation ou le filtrage des éléments.
Exemple : Tri d’une liste de tuples par le deuxième élément
# Liste de tuples
éléments = [(1, 'b'), (2, 'a'), (3, 'c')]
# Tri de la liste en utilisant lambda comme clé
éléments_triés = sorted(éléments, key=lambda x: x[1])
print(éléments_triés) # Output : [(2, 'a'), (1, 'b'), (3, 'c')]
Parfois, il est nécessaire d’utiliser une fonction une seule fois sans la définir explicitement. Les lambdas sont idéales pour ces cas temporaires.
Exemple : Calcul rapide sans assignation
# Utilisation immédiate de la lambda
résultat = (lambda x, y: x * y)(4, 5)
print(résultat) # Output : 20
Les expressions lambda peuvent capturer des variables de leur environnement, créant ainsi des fermetures. Cela permet à la lambda de se souvenir des valeurs des variables au moment de sa création.
Exemple
def externe(x):
def interne(y):
return x + y
return interne
Exemple
# Création d'une closure
closure1 = externe(5)
closure2 = externe(10)
# Appel des closures
print(closure1(3)) # Affiche 8
print(closure2(3)) # Affiche 13
Les expressions lambda peuvent capturer des variables de leur environnement, créant ainsi des fermetures. Cela permet à la lambda de se souvenir des valeurs des variables au moment de sa création.
Exemple
def externe(x):
return lambda y: x + y
Dans cet exemple, la fonction externe
prend un paramètre x
et retourne une
expression lambda qui prend un paramètre y
. L’expression lambda retourne la somme de
x
et y
.
Exemple
# Création d'une closure
closure1 = externe(5)
closure2 = externe(10)
# Appel des closures
print(closure1(3)) # Affiche 8
print(closure2(3)) # Affiche 13
Exemple
La fonction externe
retourne la fonction lambda, qui est une closure. La closure a accès à
la variable x
qui a été définie dans la fonction externe
, même après que la
fonction externe
ait terminé son exécution.
Lorsque nous créons des instances de la closure en appelant la fonction externe
avec des
valeurs différentes pour x
, nous obtenons des closures qui ont des valeurs différentes pour
x
. Cependant, chaque closure a toujours accès à la valeur de x
qui a été
définie lors de sa création.
Les lambdas sont très utiles dans les fonctions d’ordre supérieur, c’est-à-dire des fonctions qui prennent d’autres fonctions en paramètre ou qui en retournent.
Une fonction d'ordre supérieur (ou higher-order function en anglais) est une fonction qui prend une ou plusieurs fonctions en paramètre, ou qui retourne une fonction en tant que résultat. Ces fonctions sont un concept clé en programmation fonctionnelle, permettant de créer du code plus flexible et réutilisable.
Caractéristiques des fonctions d'ordre supérieur
Exemple : Utilisation avec reduce
from functools import reduce
# Liste de nombres
nombres = [1, 2, 3, 4]
# Utilisation de lambda avec reduce pour calculer la somme
somme = reduce(lambda acc, x: acc + x, nombres)
print(somme) # Output : 10
Exemple : Utilisation avec reduce
reduce
:reduce
prend deux arguments principaux :
Exemple : Utilisation avec reduce
Dans ce cas, la fonction passée est une expression lambda :
Cette lambda prend deux paramètres : - acc
(l’accumulateur) : C’est le total accumulé à
chaque étape de l’itération. - x
: C’est l’élément courant de la liste.
Ce que fait la lambda : Elle additionne l’accumulateur acc
et l’élément
courant x
à chaque étape.
Exemple : Utilisation avec reduce
reduce
fonctionne étape par étape :
reduce
prend les deux premiers éléments de la liste : 1
et
2
.
acc = 1
et x = 2
, donc
1 + 2 = 3
.
reduce
prend le résultat précédent (3
) et le troisième élément de
la liste (3
).
acc = 3
et x = 3
, donc
3 + 3 = 6
.
reduce
prend le résultat précédent (6
) et le dernier élément de la
liste (4
).
acc = 6
et x = 4
, donc
6 + 4 = 10
.
Le résultat final est donc la somme de tous les éléments de la liste : 10.
Les expressions lambda sont un outil puissant dans Python, facilitant l’écriture de code plus propre et plus efficace, surtout lorsqu’elles sont utilisées en combinaison avec des fonctions d’ordre supérieur et des opérations sur des collections.