À quoi servent les fonctions lambdas en Python
- 2021-09-21
- Publié par : Christophe DELEUZE
- Catégorie : Python
Je vous propose une introduction aux expressions lambda en Python : à quoi elles servent, quand les utiliser et quand il est préférable de les éviter.
L'expression lambda en Python
Le mot-clé lambda en Python fournit un raccourci pour déclarer de petites fonctions anonymes. Les fonctions lambda se comportent comme des fonctions normales déclarées avec le mot-clé def. Elles peuvent être utilisées chaque fois que des objets de type fonction sont requis.
Par exemple, voici comment vous définiriez une fonction lambda simple effectuant une addition :
>>> addition = lambda x, y: x + y
>>> addition(5, 3)
8
Vous pouvez déclarer la même fonction addition avec le mot-clé def :
>>> def addition(x, y):
... return x + y
>>> addition(5, 3)
8
Maintenant, vous vous demandez peut-être : pourquoi tant d’histoires à propos des lambda ? Quel est le problème ? Pour y répondre, regardons ensemble l’exemple suivant :
>>> (lambda x, y: x + y)(5, 3)
8
Que s’est-il passé ici ? Nous avons défini, sur une ligne et à la volée, une fonction lambda dont le rôle est de faire une addition, puis nous l’avons appelé directement avec les arguments 5 et 3.
Conceptuellement, dans l’exemple que nous venons de voir, utiliser une expression lambda revient au même que de déclarer une fonction à l’aide du mot-clé def avec toutefois comme différences subtiles le fait que :
- L’expression
lambdaa été écrite sur une ligne ; - L’expression
lambdan’a pas été liée à un nom commeadditionavant de l’utiliser.
En effet, nous avons simplement indiqué l’expression que nous voulions calculer, puis nous l’avons immédiatement évaluée en l’appelant comme une fonction régulière.
Il existe une autre différence syntaxique entre les définitions lambda et les définitions de fonctions régulières : les fonctions lambda sont limitées à une seule expression. Cela signifie qu’une fonction lambda ne peut pas utiliser d’instructions ou d’annotations, pas même une instruction return.
Comment renvoyons-nous les valeurs d’une lambda alors ? La réponse est simple, l’exécution d’une fonction lambda évalue son expression, puis renvoie automatiquement son résultat. Il y a donc toujours une instruction return implicite. C’est pourquoi certaines personnes appellent les lambdas des : fonctions à expression unique.
Quand utiliser une fonction lambda ?
Quand devez-vous utiliser les fonctions lambda dans votre code ? Techniquement, chaque fois que vous êtes censé fournir un objet fonction, vous pouvez utiliser une expression lambda. Et comme une expression lambda peut être anonyme, vous n’avez même pas besoin de l’attribuer à un nom.
Cela peut fournir un raccourci pratique pour définir une fonction en Python. Un cas d’utilisation fréquent pour les lambdas est par exemple l’écriture de fonctions à clés courtes et concises pour trier des itérables par une clé alternative :
>>> sorted(range(-5, 6), key=lambda x: x ** 2)
[0, -1, 1, -2, 2, -3, 3, -4, 4, -5, 5]
Comme les fonctions imbriquées normales, les lambdas fonctionnent également comme des fermetures lexicales. Une fermeture lexicale est une fonction qui mémorise les valeurs de la portée lexicale englobante même lorsque le flux du programme n’est plus dans cette portée. Voici un exemple (assez académique) pour illustrer l’idée :
>>> def fabriquer_une_addition(n):
... return lambda x: x + n
>>> plus_3 = fabriquer_une_addition(3)
>>> plus_5 = fabriquer_une_addition(5)
>>> plus_3(4)
7
>>> plus_5(4)
9
Dans l’exemple ci-dessus, l’expression lambda x: x + n peut toujours accéder à la valeur de n même si elle a été définie dans la fonction fabriquer_une_addition (la portée englobante).
Parfois, l’utilisation d’une fonction lambda au lieu d’une fonction imbriquée déclarée avec def peut exprimer son intention plus clairement. Mais pour être honnête, ce n’est pas un phénomène courant.
Quand s'abstenir d'utiliser une fonction lambda ?
Quand s’abstenir d’utiliser une fonction lambda ?
Les fonctions lambda sont des outils formidables qui doivent être utilisées avec parcimonie et avec un soin extraordinaire.
Si vous êtes tenté d’utiliser un lambda, prenez quelques secondes (ou minutes) pour vous demander si c’est vraiment le moyen le plus propre et le plus facile à maintenir pour obtenir le résultat souhaité.
Par exemple, faire quelque chose comme ça pour enregistrer deux lignes de code est tout simplement stupide. Bien sûr, cela fonctionne techniquement et c’est un “truc” assez sympa. Mais cela va également dérouter la prochaine personne qui devra envoyer un correctif de bogue dans un délai serré :
# Pas cool
>>> class Voiture:
... roule = lambda self: print('Wroom!')
... crash = lambda self: print('Boom!')
>>> ma_voiture = Voiture()
>>> ma_voiture.roule()
'Wroom!'
>>> ma_voiture.crash()
'Boom!'
Nous pouvons ressentir la même chose à propos de la complexité des fonctions map() ou des filter() utilisant des lambdas. Habituellement, il est beaucoup plus propre d’utiliser une compréhension de liste ou une expression génératrice :
# Pas cool du tout !
>>> list(filter(lambda x: x % 2 == 0, range(16)))
[0, 2, 4, 6, 8, 10, 12, 14]
# Mieux
>>> [x for x in range(16) if x % 2 == 0]
[0, 2, 4, 6, 8, 10, 12, 14]
Si vous vous retrouvez à faire quelque chose de complexe avec une expression lambda, envisagez plutôt de définir une fonction réelle avec un nom qui lui sera propre.
Enregistrer quelques lignes en plus dans un projet n’a pas d’importance à long terme. Par contre, vos collègues (et votre futur vous-même) apprécieront un code propre et lisible n’abusant pas des expressions lambdas.
Le mot de la fin
Pour résumer ce que nous venons de voir :
- Les fonctions
lambdasont des fonctions à expression unique qui ne sont pas nécessairement liées à un nom (anonymes) ; - Les fonctions
Lambdane peuvent pas utiliser d’instructions Python classiques et incluent toujours une instructionreturnimplicite ; - Demandez-vous toujours : l’utilisation d’une fonction régulière (nommée) ou d’une expression de liste/générateur offrirait-elle plus de clarté ?
C’est fini pour aujourd’hui, vous pouvez retourner à votre café et n’hésitez à me laisser un commentaire si vous avez des questions ou des remarques à partager.