ProgrammationDéveloppeur Python

Parlez des fonctions lambda en Python. Quelles sont leurs limitations par rapport aux fonctions ordinaires ? Dans quelles situations sont-elles préférables et dans quelles situations sont-elles indésirables ?

Réussissez les entretiens avec l'assistant IA Hintsage

Réponse

Fonction lambda — c'est une fonction anonyme (sans nom), définie à l'aide du mot-clé lambda. Elle est généralement utilisée là où une fonction courte est nécessaire "une fois et sur place".

add = lambda x, y: x + y print(add(1, 2)) # 3

Limitations des fonctions lambda :

  • Une lambda ne peut contenir qu'une seule expression — celle qui est aussi la valeur de retour, il n'est pas possible d'effectuer des calculs multi-lignes, d'utiliser return, ou des conditions de type if-else (uniquement sous forme d'une expression ternaire).
  • Il est impossible d'utiliser un code complexe avec try/except, des boucles, etc.
  • La fonction lambda ne possède pas de documentation complète (il n'est pas possible d'ajouter de docstring).
  • La fonction lambda est moins lisible, surtout si elle est imbriquée.

Quand la lambda est utile :

  • Dans des clés de tri/filtrage sur une seule ligne (arguments key ; par exemple dans sorted, filter, map).
  • Lorsque la réutilisation du code n'est pas nécessaire — pour des opérations locales, pour rapidement "insérer une fonction".

Quand il est préférable d'éviter la lambda :

  • Dans une logique complexe : pour la réutilisation, avec beaucoup de code ou de conditions, pour la clarté et la lisibilité, il est préférable d'extraire dans une fonction def avec un nom et un docstring.

Question piège

Question : Les fonctions lambda peuvent-elles utiliser des variables du contexte externe, et comment cela influence-t-il leur comportement lorsqu'elles sont utilisées à l'intérieur de boucles ?

Réponse : Les fonctions lambda peuvent capturer des variables du contexte externe (fermeture lexicale). Lorsqu'elles sont définies à l'intérieur d'une boucle, cela conduit souvent à un comportement inattendu — la lambda utilise la valeur actuelle de la variable au moment de l'appel, et non celle qui "était au moment de la définition".

funcs = [] for i in range(3): funcs.append(lambda: i) # toutes les fonctions retourneront 2 (i=2 après la boucle) print([f() for f in funcs]) # [2, 2, 2]

Pour capturer la valeur "ancienne" :

funcs = [] for i in range(3): funcs.append(lambda i=i: i) print([f() for f in funcs]) # [0, 1, 2]

Exemples d'erreurs réelles dues à une méconnaissance des subtilités du sujet


Histoire

Dans un projet, une lambda a été utilisée pour filtrer une liste de dictionnaires par une clé spécifique. La lambda à l'intérieur de la boucle a capturé une variable qui, au moment de l'appel, avait une autre (inattendue) valeur. Résultat — un filtrage incorrect et des erreurs dans les rapports.


Histoire

Un grand projet sur Django : une forme de validation complexe, mise en œuvre comme une longue expression à l'intérieur d'une fonction lambda. Par la suite, la logique métier a changé, la lambda ne pouvait plus contenir tout le code, il a fallu réécrire en une fonction ordinaire. La lambda a ralenti le débogage.


Histoire

Dans une startup, une lambda a été mal utilisée pour transmettre une fonction de tri, oubliant qu'elle renvoie un type incorrect (par exemple, pas un tuple mais une liste). Cela a conduit à un tri imprévisible et à des bugs lors de la dé-duplication des données.