Fonctions Python Lambda : syntaxe, utilisations réelles et quand ne pas les utiliser

  1. Accueil
  2. Blog
  3. Développement de logiciels

Développement de logiciels

Fonctions Python Lambda : Syntaxe, utilisations réelles et quand ne pas les utiliser

Un lambda est une petite fonction que vous pouvez écrire sur une seule ligne, là où vous en avez besoin. Apprenez la syntaxe, les endroits où les lambdas aident réellement, le piège qui attrape les développeurs expérimentés et quand une fonction normale est tout simplement meilleure.

8 min de lecture
Fonctions Python lambda : syntaxe, utilisations réelles et quand ne pas les utiliser

À retenir

  • Un lambda est une fonction anonyme limitée à une seule expression.
  • Sa meilleure utilisation est comme argument court, en particulier le key pour sorted, min et max.
  • La compréhension d’une liste est généralement plus claire que map ou filter avec un lambda.
  • Si vous attribuez un lambda à un nom, écrivez plutôt un def.

Vous devez trier les produits par prix. Écrire une fonction nommée distincte juste pour dire « utiliser le prix » ressemble à beaucoup de cérémonie. Les fonctions Python lambda vous permettent de définir ce petit élément de logique en ligne, exactement là où vous l’utilisez.

Les lambdas sont pratiques, mais ils sont également faciles à abuser. Ce guide montre où ils aident vraiment et où ils rendent le code plus difficile à lire. Nous avons exécuté chaque exemple sur Python 3.13 et le résultat affiché provient de cette exécution.

Qu’est-ce qu’un lambda ?

Un lambda est une fonction sans nom, écrite avec le mot clé lambda :

lambda arguments: expression

Il prend n’importe quel nombre d’arguments et renvoie automatiquement la valeur d’une seule expression. Il n’y a pas de mot-clé return ni de corps d’instructions.

square = lambda x: x * x
print(square(4))                     # 16

print((lambda a, b=10: a + b)(5))    # 15

La deuxième ligne définit un lambda avec un argument par défaut et l’appelle immédiatement. Vous écririez rarement cela dans du code réel, mais cela montre qu’un lambda est un objet fonction ordinaire.

lambda contre déf

Ces deux produits produisent des fonctions qui se comportent de la même manière :

square = lambda x: x * x

def square_def(x):
    return x * x

print(square(4), square_def(4))                 # 16 16
print(square.__name__, square_def.__name__)     # <lambda> square_def

Regardez les noms. Chaque lambda est simplement appelé <lambda>, donc les messages d’erreur et les journaux ne peuvent pas vous dire lequel a échoué. C’est la principale raison pour laquelle les guides de style tels que PEP 8 recommandent un def chaque fois que vous souhaitez donner un nom à une fonction.

Caractéristique lambda déf
Nom Anonyme Nommé
Corps Une expression N’importe quel nombre de déclarations
Retour Implicite Explicite return
Docstring et astuces de type Non pris en charge Pris en charge
Tracebacks lisibles Spectacles <lambda> Affiche le nom
Idéal pour Arguments courts et jetables Tout le reste

Tri avec clé : la meilleure utilisation

Les fonctions telles que sorted, min et max acceptent une fonction key qui décide quoi comparer. C’est là que les lambdas brillent :

products = [("pen", 10), ("bag", 900), ("book", 250)]

sorted(products, key=lambda p: p[1])
# [('pen', 10), ('book', 250), ('bag', 900)]

max(products, key=lambda p: p[1])
# ('bag', 900)

Pour trier selon plusieurs éléments, renvoyez un tuple. Ici, les gens sont triés par âge, les plus âgés d’abord, puis par nom :

people = [{"name": "Asha", "age": 31}, {"name": "Ben", "age": 25},
          {"name": "Dev", "age": 31}]

[p["name"] for p in sorted(people, key=lambda p: (-p["age"], p["name"]))]
# ['Asha', 'Dev', 'Ben']

Le signe moins inverse l’ordre du nombre uniquement. Parfois, vous n’avez pas du tout besoin d’un lambda, car une fonction existante fait déjà le travail. Comparez le tri par défaut avec un tri insensible à la casse :

names = ["Asha", "ben", "Chitra", "dev"]

sorted(names)                  # ['Asha', 'Chitra', 'ben', 'dev']
sorted(names, key=str.lower)   # ['Asha', 'ben', 'Chitra', 'dev']

La valeur par défaut place tous les mots en majuscules en premier. Passer str.lower corrige cela sans aucun lambda. Le module operator propose des aides similaires, telles que itemgetter(1) pour lambda p: p[1].

cartographier et filtrer

map applique une fonction à chaque élément et filter conserve les éléments pour lesquels il renvoie vrai. Les deux fonctionnent avec des lambdas, mais comparez chacun avec une compréhension de liste :

nums = [1, 2, 3, 4, 5, 6]

list(map(lambda n: n * 10, nums))      # [10, 20, 30, 40, 50, 60]
[n * 10 for n in nums]                 # [10, 20, 30, 40, 50, 60]

list(filter(lambda n: n % 2 == 0, nums))   # [2, 4, 6]
[n for n in nums if n % 2 == 0]            # [2, 4, 6]

Les résultats sont identiques et la plupart des développeurs Python trouvent les compréhensions plus faciles à lire. Notez également que map et filter renvoient des itérateurs paresseux, vous avez donc besoin de list() pour voir les valeurs. Notre guide de Compréhension des listes Python couvre ce style en profondeur. map se lit toujours bien avec une fonction nommée existante, comme dans map(str.strip, lines).

réduire

functools.reduce combine les éléments en une seule valeur, portant un résultat courant :

from functools import reduce

reduce(lambda acc, n: acc + n, nums, 0)   # 21
sum(nums)                                 # 21

Pour les tâches courantes, telles que les totaux, utilisez un élément intégré tel que sum, max ou any. Gardez reduce pour les cas plus rares et envisagez une boucle simple si le lambda commence à paraître compliqué.

Conditions dans un lambda

Vous ne pouvez pas utiliser une instruction if dans un lambda, mais vous pouvez utiliser une expression conditionnelle :

label = lambda total: "large" if total >= 1000 else "small"

label(1200), label(300)
# ('large', 'small')

Une condition est bonne. Une fois que vous commencez à les imbriquer, les lecteurs doivent travailler dur, ce qui est un signe clair pour passer à un def avec des instructions if ordinaires.

Lambdas qui renvoient des fonctions

Une fonction peut créer et renvoyer un lambda qui mémorise une valeur de son environnement :

def multiplier(n):
    return lambda x: x * n

double = multiplier(2)
double(7)   # 14

Cela fonctionne grâce aux fermetures, que notre article sur les Fermetures JavaScript explique dans un langage différent. Python functools.partial propose une autre façon de pré-remplir les arguments.

Le piège de la liaison tardive

Cela finit par attraper presque tout le monde. Nous avons créé trois lambdas dans une boucle, en attendant que chacun renvoie son propre numéro :

funcs = [lambda: i for i in range(3)]
[f() for f in funcs]

# [2, 2, 2]

Tous les trois renvoient 2. Un lambda ne capture pas la valeur de i lors de sa création. Il recherche la variable lorsqu’elle est appelée, et la boucle est alors terminée, laissant i à 2. La solution habituelle consiste à capturer la valeur comme argument par défaut, puisque les valeurs par défaut sont évaluées au moment de la définition :

funcs = [lambda i=i: i for i in range(3)]
[f() for f in funcs]

# [0, 1, 2]

Ceci n’est pas propre aux lambdas, car un def à l’intérieur d’une boucle se comporte de la même manière. Il apparaît simplement plus souvent avec les lambdas, car ils sont si souvent créés dans des boucles, par exemple lors de l’attachement de rappels de boutons.

Conseil : Si vous avez besoin d’une fonction par élément, demandez-vous si vous avez besoin de plusieurs fonctions. Souvent, une seule fonction qui prend l’élément comme argument est plus claire et évite complètement le piège.

Tables de recherche de petites fonctions

Les lambdas s’intègrent parfaitement dans un dictionnaire qui mappe les noms à de petites opérations :

ops = {
    "add": lambda a, b: a + b,
    "sub": lambda a, b: a - b,
}

ops["sub"](10, 3)   # 7

Cela peut remplacer une longue chaîne de if et elif. Le guide Dictionnaire Python couvre davantage de modèles de dictionnaire, et le module operator fournit déjà operator.add et operator.sub.

Limites des lambdas

  • Une seule expression. Aucune affectation avec =, pas de boucles et pas de blocs try.
  • Aucune déclaration. L’écriture de lambda x: return x échoue avec un SyntaxError, comme notre test l’a confirmé.
  • Pas d’indications de docstring ou de type. Les outils et les lecteurs reçoivent moins d’aide.
  • Débogage plus difficile. Les erreurs pointent vers <lambda> plutôt que vers un nom utile.

Bien entendu, les Lambdas peuvent toujours déclencher des exceptions. Leur gestion fonctionne de la même manière que pour n’importe quelle fonction, comme expliqué dans Gestion des exceptions Python.

Quand ne pas utiliser un lambda

Situation Meilleur choix
Lui attribuer un nom déf
La logique a besoin de plus d’une ligne déf
Transformer ou filtrer une liste Une compréhension de liste
Additionner ou trouver un maximum sum, max, min
Obtenir un élément ou un attribut operator.itemgetter ou attrgetter
Le même lambda apparaît à plusieurs endroits Une fonction nommée que vous pouvez tester

Ce dernier point est important. Une logique qui mérite d’être réutilisée vaut la peine d’être testée, et une fonction nommée est beaucoup plus facile à tester, comme le montre notre tutoriel pytest.

Pour conclure

Un bon lambda est suffisamment court pour être lu d’un seul coup d’œil et utilisé une seule fois, généralement comme argument. Les clés de tri sont l’exemple classique. Pour vérifier votre propre code, recherchez = lambda et transformez-le en fonctions nommées. Ensuite, regardez n’importe quel map ou filter avec un lambda et voyez si une compréhension se lit mieux.

Questions fréquentes

Qu’est-ce qu’une fonction lambda en Python ?

C’est une petite fonction anonyme créée avec le mot-clé lambda. Il prend des arguments et renvoie la valeur d’une seule expression, sans nom ni instruction de retour.

Un Python lambda peut-il avoir plusieurs lignes ?

Non. Un lambda est limité à une seule expression. Vous pouvez le diviser en lignes entre parenthèses, mais il ne peut toujours pas contenir d’instructions, utilisez donc def pour une logique plus complexe.

Puis-je utiliser if else dans un lambda ?

Vous pouvez utiliser une expression conditionnelle, telle que lambda x : “big” si x > 10 sinon “small”. Une instruction if avec un bloc n’est pas autorisée.

Les lambdas sont-ils plus rapides que les fonctions normales ?

Pas de manière significative. Les deux créent le même type d’objet fonction. Choisissez entre eux pour la lisibilité et non pour les performances.

Dois-je utiliser une carte avec lambda ou une compréhension de liste ?

La plupart des développeurs Python préfèrent une compréhension de liste pour plus de lisibilité. map est raisonnable lorsque vous avez déjà une fonction nommée, telle que map(str.strip, lines).

Continuez à apprendre

Travailler avec Stack Quora

Besoin d’aide pour les tests, WordPress ou le référencement ?

Nous aidons les équipes à proposer de meilleurs logiciels et à développer leurs sites. Dites-nous sur quoi vous travaillez et nous vous proposerons une prochaine étape claire.

Continuez à lire

Plus de guides sur tests, IA et développement moderne

Vous avez apprécié cet article ? Choisissez un sujet et accédez directement à nos nouveaux didacticiels.

Intelligence artificielle

Les hallucinations de l'IA expliquées : pourquoi les modèles de langage inventent les choses et comment les réduire

Les hallucinations de l'IA ont expliqué : ce qu'elles sont, pourquoi les modèles de langage les produisent, les types courants, comment les réduire …

Lire l'article →
DevOps

Variables d'environnement expliquées : fichiers .env, secrets et configuration correctement effectués

Variables d'environnement expliquées avec des exemples Python que nous avons exécutés : lecture et définition, pourquoi chaque valeur est une chaîne…

Lire l'article →
Développement logiciel

Limitation du débit de l'API expliquée : algorithmes, en-têtes et gestion des erreurs 429

Limitation du débit de l'API expliquée avec une simulation que nous avons exécutée : compartiment de jetons, fenêtre fixe, fenêtre glissante, 429 ré…

Lire l'article →
Automatisation des tests

Se moquer en Python : unittest.mock, patch et les erreurs qui font mentir les tests

Moquerie en Python avec unittest.mock, testée : Mock et return_value, side_effect, correctifs où un nom est utilisé, spec et autospec, dates moqueus…

Lire l'article →
Tests logiciels

Couverture du code expliquée : couverture des lignes par rapport aux branches et ce que signifie réellement 100 %

Couverture du code expliquée avec une véritable exécution de cover.py : couverture des lignes, des branches et des conditions, lecture d'un rapport,…

Lire l'article →
Bases de données et SQL

DELETE vs TRUNCATE vs DROP dans SQL : différences, restauration et quand les utiliser

DELETE vs TRUNCATE vs DROP expliqué avec SQL testé : ce que chacun supprime, restauration, déclencheurs, réinitialisation d'identité, vitesse et en …

Lire l'article →
Bases de données et SQL

Vues SQL expliquées : créez, utilisez et évitez les pièges, avec des exemples

Vues SQL expliquées avec les requêtes que nous avons exécutées : création d'une vue, résultats en direct, masquage des colonnes, performances, vues …

Lire l'article →
Développement logiciel

Interface TypeScript vs Type : différences réelles, testées avec le compilateur

Interface TypeScript vs type, vérifiée avec le vrai compilateur : ce que les deux peuvent faire, ce qu'un seul peut faire, la fusion des déclaration…

Lire l'article →
Développement logiciel

Python *args et **kwargs expliqués : fonctions flexibles avec des exemples clairs

Python *args et **kwargs expliqués avec le code que nous avons exécuté : emballage et déballage, ordre des paramètres, arguments de mot-clé uniqueme…

Lire l'article →
Développement logiciel

Fonctions Python Lambda : syntaxe, utilisations réelles et quand ne pas les utiliser

Fonctions Python lambda expliquées avec le code que nous avons exécuté : syntaxe, tri avec clé, carte et filtre, fermetures, piège de liaison tardiv…

Lire l'article →
Intelligence artificielle

Que sont les agents IA ? Comment ils fonctionnent, avec une simple boucle d'agent que vous pouvez exécuter

Que sont les agents IA ? Un guide simple sur la boucle d'agent, les outils, la mémoire et les garde-fous, avec une petite boucle Python que nous avo…

Lire l'article →
DevOps

Surveillance vs observabilité : la vraie différence, avec les journaux, les métriques et les traces

Surveillance et observabilité expliquées : échecs connus et inconnus, journaux, métriques et traces, présentation pas à pas des incidents de paiemen…

Lire l'article →
DevOps

Volumes Docker vs montages Bind : conserver les données du conteneur de la bonne manière

Volumes Docker et montages de liaison expliqués : pourquoi les données du conteneur disparaissent, volumes nommés, montages de liaison, tmpfs, exemp…

Lire l'article →
Automatisation des tests

TDD vs BDD : principales différences, une fonctionnalité conçue dans les deux sens et quand les utiliser

TDD vs BDD expliqué avec une fonctionnalité de remise construite dans les deux sens : refactor rouge-vert avec le code que nous avons exécuté, scéna…

Lire l'article →
Développement logiciel

Git merge vs rebase : différences, exemples et quand utiliser chacun

Git merge vs rebase expliqué avec de vraies sorties de log, un tableau comparatif, la règle d'or du rebase et un flux de travail sûr pour les équipes.

Lire l'article →
Développement logiciel

List comprehension Python : syntaxe, exemples et cas à éviter

La list comprehension Python expliquée : syntaxe, filtres, if-else, boucles imbriquées, temps mesurés et cas où une boucle for classique est préféra…

Lire l'article →
Bases de données et SQL

Jointures SQL expliquées avec exemples (Inner, Left, Right, Full)

Comprenez les jointures SQL pas à pas avec des tables et requêtes d'exemple : INNER, LEFT, RIGHT, FULL, CROSS et SELF, plus erreurs courantes et con…

Lire l'article →