Qu'est-ce qui est le plus préférable à utiliser: les fonctions lambda ou les fonctions imbriquées ('def')?

102

J'utilise principalement des fonctions lambda mais j'utilise parfois des fonctions imbriquées qui semblent fournir le même comportement.

Voici quelques exemples triviaux où ils font fonctionnellement la même chose si l'un ou l'autre était trouvé dans une autre fonction:

Fonction Lambda

>>> a = lambda x : 1 + x
>>> a(5)
6

Fonction imbriquée

>>> def b(x): return 1 + x

>>> b(5)
6

Y a-t-il des avantages à utiliser l'un par rapport à l'autre? (Performances? Lisibilité? Limitations? Cohérence? Etc.)

Cela a-t-il même une importance? Si ce n'est pas le cas, cela viole le principe pythonique:

Il devrait y avoir une - et de préférence une seule - façon évidente de le faire .

Rayon
la source

Réponses:

106

Si vous devez attribuer le lambdaà un nom, utilisez defplutôt un . defLes s ne sont que du sucre syntaxique pour une affectation, donc le résultat est le même, et ils sont beaucoup plus flexibles et lisibles.

lambdas peut être utilisé une seule fois, jetez les fonctions qui n'auront pas de nom.

Cependant, ce cas d'utilisation est très rare. Vous avez rarement besoin de faire circuler des objets de fonction sans nom.

Les objets intégrés map()et filter()nécessitent des fonctions, mais listent les compréhensions et les expressions génératrices sont généralement plus lisibles que ces fonctions et peuvent couvrir tous les cas d'utilisation, sans avoir besoin de lambdas.

Pour les cas où vous avez vraiment besoin d'un petit objet fonction, vous devez utiliser les operatorfonctions du module, comme operator.addau lieu delambda x, y: x + y

Si vous en avez toujours besoin lambdanon couvert, vous pouvez envisager d'écrire un def, juste pour être plus lisible. Si la fonction est plus complexe que celles du operatormodule, a defest probablement meilleure.

Ainsi, les bons lambdacas d'utilisation du monde réel sont très rares.

nosklo
la source
9
Je suis d'accord avec la réponse pour savoir quand l'utiliser lambda, mais je ne suis pas d'accord pour dire que c'est "très rare", c'est courant pour les fonctions clés à sortedou itertools.groupbyetc., par exemplesorted(['a1', 'b0'], key= lambda x: int(x[1]))
Chris_Rands
30

En pratique, pour moi, il y a deux différences:

Le premier concerne ce qu'ils font et ce qu'ils retournent:

  • def est un mot-clé qui ne renvoie rien et crée un 'nom' dans l'espace de noms local.

  • lambda est un mot-clé qui renvoie un objet fonction et ne crée pas de «nom» dans l'espace de noms local.

Par conséquent, si vous devez appeler une fonction qui prend un objet fonction, la seule façon de le faire dans une ligne de code python est d'utiliser un lambda. Il n'y a pas d'équivalent avec def.

Dans certains cadres, c'est en fait assez courant; par exemple, j'utilise beaucoup Twisted , et je fais donc quelque chose comme

d.addCallback(lambda result: setattr(self, _someVariable, result))

est assez courant, et plus concis avec les lambdas.

La deuxième différence concerne ce que la fonction réelle est autorisée à faire.

  • Une fonction définie avec 'def' peut contenir n'importe quel code python
  • Une fonction définie avec 'lambda' doit s'évaluer en une expression, et ne peut donc pas contenir d'instructions telles que print, import, rise, ...

Par exemple,

def p(x): print x

fonctionne comme prévu, tandis que

lambda x: print x

est une SyntaxError.

Bien sûr, il existe des solutions de contournement: remplacez-les printpar sys.stdout.writeou importpar __import__. Mais généralement, il vaut mieux utiliser une fonction dans ce cas.

Thomas Vander Stichele
la source
23

Dans cette interview, Guido van Rossum dit qu'il souhaite ne pas avoir laissé `` lambda '' entrer en Python:

" Q. De quelle fonctionnalité de Python êtes-vous le moins satisfait?

Parfois, j'ai été trop rapide pour accepter les contributions et j'ai réalisé plus tard que c'était une erreur. Un exemple serait certaines des fonctionnalités de programmation fonctionnelle, telles que les fonctions lambda. Lambda est un mot-clé qui vous permet de créer une petite fonction anonyme; des fonctions intégrées telles que mapper, filtrer et réduire exécutent une fonction sur un type de séquence, comme une liste.

En pratique, cela ne s'est pas très bien passé. Python n'a que deux étendues: locale et globale. Cela rend l'écriture de fonctions lambda douloureuse, car vous souhaitez souvent accéder aux variables dans la portée où le lambda a été défini, mais vous ne pouvez pas en raison des deux portées. Il y a un moyen de contourner cela, mais c'est quelque chose d'un kludge. Souvent, il semble beaucoup plus facile en Python d'utiliser simplement une boucle for au lieu de jouer avec les fonctions lambda. la carte et les amis ne fonctionnent bien que lorsqu'il existe déjà une fonction intégrée qui fait ce que vous voulez.

À mon humble avis, les Iambdas peuvent parfois être pratiques, mais sont généralement pratiques au détriment de la lisibilité. Pouvez-vous me dire ce que cela fait:

str(reduce(lambda x,y:x+y,map(lambda x:x**x,range(1,1001))))[-10:]

Je l'ai écrit et il m'a fallu une minute pour le comprendre. Cela vient du projet Euler - je ne dirai pas quel problème parce que je déteste les spoilers, mais cela fonctionne en 0,124 seconde :)

Chris Lawlor
la source
20
Notez que l'interview est plutôt ancienne et que Python a depuis longtemps ajouté des portées imbriquées, ce qui rend l'argument qu'il donne contre lambda plus pertinent. Je suis sûr qu'il regrette toujours lambda, mais pas assez pour le supprimer dans Python 3.0.
Thomas Wouters
10
Vraiment, votre exemple devrait être un argument contre les one-liners, pas les lambdas. De plus, vous devriez avoir utilisé la fonction sum intégrée au lieu de réduire avec un lambda: str (sum (map (lambda x: x ** x, range (1001)))) [: - 10]
Triptyque
2
@ThomasWouters: Je comprends que lambdane pas être supprimé dans la 3.0 était une chose proche, et que Guido ne se battait pas pour le garder.
Ethan Furman
11

Pour n = 1000, voici le temps d'appeler une fonction par rapport à un lambda:

In [11]: def f(a, b):
             return a * b

In [12]: g = lambda x, y: x * y

In [13]: %%timeit -n 100
for a in xrange(n):
  for b in xrange(n):
    f(a, b)
   ....:
100 loops, best of 3: 285 ms per loop

In [14]: %%timeit -n 100
for a in xrange(n):
  for b in xrange(n):
    g(a, b)
   ....:
100 loops, best of 3: 298 ms per loop

In [15]: %%timeit -n 100
for a in xrange(n):
  for b in xrange(n):
    (lambda x, y: x * y)(a, b)
   ....:
100 loops, best of 3: 462 ms per loop
Andy Hayden
la source
3
Intéressant de voir que les versions lambda et définies sont à peu près équivalentes. Le dernier test a pris plus de temps car python avait probablement besoin d'allouer de l'espace à chaque fois qu'il définissait cette fonction lambda.
hlin117
Je suppose que cela a du sens car la définition peut faire référence à des variables locales (qui peuvent avoir changé) ... bien que dans le cas où ce n'est pas le cas, comme ici, cpython pourrait faire un meilleur travail.
Andy Hayden
Utilisez dis.dis; Votre (lambda x, y: x * y) crée la fonction à chaque boucle. Si vous créez le lambda avant la boucle (aka f = lambda x, y: x * y), le bytecode pour appeler la fonction sera exactement le même que g / f dans votre exemple précédent, donc les performances lambda sont les mêmes comme une fonction def. Donc lambda ou def comme aucun impact si vous l'utilisez de la même manière. Faites l'inverse, déclarez la fonction f () dans la boucle, puis appelez-la ...
tito
@tito Je crois que c'est précisément ce que démontrent les 3 exemples chronométrés ...
Andy Hayden
@tito oh, vous dites définir la fonction dans la boucle, bien sûr, mais je dirais que c'est un modèle inhabituel. Je ne sais pas pourquoi cela nécessitait un vote négatif sur ce commentaire ...
Andy Hayden
7

Performance:

Créer une fonction avec lambdaest légèrement plus rapide que la créer avec def. La différence est due à la defcréation d'une entrée de nom dans la table locale. La fonction résultante a la même vitesse d'exécution.


Lisibilité:

Les fonctions Lambda sont un peu moins lisibles pour la plupart des utilisateurs de Python, mais aussi beaucoup plus concises dans certaines circonstances. Envisagez de passer d'une routine non fonctionnelle à une routine fonctionnelle:

# Using non-functional version.

heading(math.sqrt(v.x * v.x + v.y * v.y), math.atan(v.y / v.x))

# Using lambda with functional version.

fheading(v, lambda v: math.sqrt(v.x * v.x + v.y * v.y), lambda v: math.atan(v.y / v.x))

# Using def with functional version.

def size(v):
    return math.sqrt(v.x * v.x + v.y * v.y)

def direction(v):
    return math.atan(v.y / v.x)

deal_with_headings(v, size, direction)

Comme vous pouvez le voir, la lambdaversion est plus courte et "plus facile" dans le sens où il suffit d'ajouter lambda v:à la version non fonctionnelle d'origine pour passer à la version fonctionnelle. C'est aussi beaucoup plus concis. Mais rappelez-vous que beaucoup d'utilisateurs de Python seront confus par la syntaxe lambda, donc ce que vous perdez en longueur et en complexité réelle pourrait être récupéré dans la confusion des autres codeurs.


Limites:

  • lambda les fonctions ne peuvent être utilisées qu'une seule fois, sauf si elles sont affectées à un nom de variable.
  • lambdales fonctions affectées aux noms de variables n'ont aucun avantage sur les deffonctions.
  • lambda les fonctions peuvent être difficiles ou impossibles à décaper.
  • def Les noms des fonctions doivent être soigneusement choisis pour être raisonnablement descriptifs et uniques ou du moins autrement inutilisés dans leur portée.

Cohérence:

Python évite principalement les conventions de programmation fonctionnelle au profit d'une sémantique objective procédurale et plus simple. L' lambdaopérateur s'oppose directement à ce biais. De plus, comme alternative au déjà répandu def, la lambdafonction ajoute de la diversité à votre syntaxe. Certains jugeraient cela moins cohérent.


Fonctions préexistantes:

Comme indiqué par d'autres, de nombreuses utilisations de lambdasur le terrain peuvent être remplacées par des membres du operatorou d'autres modules. Par exemple:

do_something(x, y, lambda x, y: x + y)
do_something(x, y, operator.add)

L'utilisation de la fonction préexistante peut rendre le code plus lisible dans de nombreux cas.


Le principe pythonique: «Il devrait y avoir une - et de préférence une seule - façon évidente de le faire»

C'est similaire à la source unique de la doctrine de la vérité . Malheureusement, le principe de la manière simple et évidente de le faire a toujours été plus une aspiration mélancolique pour Python, plutôt qu'un véritable principe directeur. Considérez les très puissantes compréhensions de tableaux en Python. Ils sont fonctionnellement équivalents aux fonctions mapet filter:

[e for e in some_array if some_condition(e)]
filter(some_array, some_condition)

lambda et def sont les mêmes.

C'est une question d'opinion, mais je dirais que tout ce qui dans le langage Python destiné à un usage général qui ne casse évidemment rien est assez "pythonique".

Pi Marillion
la source
7

Plus préférable: fonctions lambda ou fonctions imbriquées ( def)?

Il y a un avantage à utiliser un lambda par rapport à une fonction régulière: ils sont créés dans une expression.

Il y a plusieurs inconvénients:

  • pas de nom (juste '<lambda>')
  • pas de docstrings
  • pas d'annotations
  • pas de déclarations complexes

Ils sont également tous deux du même type d'objet. Pour ces raisons, je préfère généralement créer des fonctions avec le defmot - clé plutôt qu'avec lambdas.

Premier point - ils sont du même type d'objet

Un lambda donne le même type d'objet qu'une fonction régulière

>>> l = lambda: 0
>>> type(l)
<class 'function'>
>>> def foo(): return 0
... 
>>> type(foo)
<class 'function'>
>>> type(foo) is type(l)
True

Puisque les lambdas sont des fonctions, ce sont des objets de première classe.

Les lambdas et les fonctions:

  • peut être passé en argument (identique à une fonction régulière)
  • lorsqu'il est créé dans une fonction externe, devient une fermeture sur les sections locales de ces fonctions externes

Mais les lambdas manquent, par défaut, de certaines choses que les fonctions obtiennent via la syntaxe de définition de fonction complète.

Un lamba __name__est'<lambda>'

Les lambdas sont des fonctions anonymes, après tout, donc ils ne connaissent pas leur propre nom.

>>> l.__name__
'<lambda>'
>>> foo.__name__
'foo'

Ainsi, les lambda ne peuvent pas être recherchés par programme dans leur espace de noms.

Cela limite certaines choses. Par exemple, foopeut être recherché avec un code sérialisé, alors que lne peut pas:

>>> import pickle
>>> pickle.loads(pickle.dumps(l))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
_pickle.PicklingError: Can't pickle <function <lambda> at 0x7fbbc0464e18>: 
attribute lookup <lambda> on __main__ failed

Nous pouvons très bien chercher foo- car il connaît son propre nom:

>>> pickle.loads(pickle.dumps(foo))
<function foo at 0x7fbbbee79268>

Les lambdas n'ont pas d'annotations et pas de docstring

Fondamentalement, les lambdas ne sont pas documentés. Réécrivons foopour être mieux documenté:

def foo() -> int:
    """a nullary function, returns 0 every time"""
    return 0

Maintenant, foo a de la documentation:

>>> foo.__annotations__
{'return': <class 'int'>}
>>> help(foo)
Help on function foo in module __main__:

foo() -> int
    a nullary function, returns 0 every time

Alors que nous n'avons pas le même mécanisme pour donner les mêmes informations aux lambdas:

>>> help(l)
Help on function <lambda> in module __main__:

<lambda> lambda (...)

Mais nous pouvons les pirater sur:

>>> l.__doc__ = 'nullary -> 0'
>>> l.__annotations__ = {'return': int}
>>> help(l)
Help on function <lambda> in module __main__:

<lambda> lambda ) -> in
    nullary -> 0

Mais il y a probablement une erreur qui gâche la sortie de l'aide, cependant.

Lambdas ne peut renvoyer qu'une expression

Lambdas ne peut pas renvoyer d'instructions complexes, uniquement des expressions.

>>> lambda: if True: 0
  File "<stdin>", line 1
    lambda: if True: 0
             ^
SyntaxError: invalid syntax

Les expressions peuvent certes être assez complexes, et si vous essayez très dur, vous pouvez probablement accomplir la même chose avec un lambda, mais la complexité supplémentaire est plus un inconvénient à l'écriture de code clair.

Nous utilisons Python pour plus de clarté et de maintenabilité. La surutilisation des lambdas peut agir contre cela.

Le seul avantage pour les lambdas: peut être créé en une seule expression

C'est le seul avantage possible. Puisque vous pouvez créer un lambda avec une expression, vous pouvez le créer à l'intérieur d'un appel de fonction.

La création d'une fonction à l'intérieur d'un appel de fonction évite la recherche de nom (peu coûteuse) par rapport à celle créée ailleurs.

Cependant, étant donné que Python est strictement évalué, il n'y a pas d'autre gain de performances que d'éviter la recherche de nom.

Pour une expression très simple, je pourrais choisir un lambda.

J'ai également tendance à utiliser des lambdas lorsque je fais du Python interactif, pour éviter plusieurs lignes quand on fera l'affaire. J'utilise le type de format de code suivant lorsque je veux passer un argument à un constructeur lors de l'appel timeit.repeat:

import timeit

def return_nullary_lambda(return_value=0):
    return lambda: return_value

def return_nullary_function(return_value=0):
    def nullary_fn():
        return return_value
    return nullary_fn

Et maintenant:

>>> min(timeit.repeat(lambda: return_nullary_lambda(1)))
0.24312214995734394
>>> min(timeit.repeat(lambda: return_nullary_function(1)))
0.24894469301216304

Je crois que la légère différence de temps ci-dessus peut être attribuée à la recherche de nom dans return_nullary_function- notez que c'est très négligeable.

Conclusion

Les lambdas sont parfaits pour les situations informelles où vous souhaitez minimiser les lignes de code en faveur de la création d'un point singulier.

Les lambdas sont mauvais pour les situations plus formelles où vous avez besoin de clarté pour les éditeurs de code qui viendront plus tard, en particulier dans les cas où ils ne sont pas triviaux.

Nous savons que nous sommes censés donner de bons noms à nos objets. Comment pouvons-nous le faire quand l'objet n'a pas nom?

Pour toutes ces raisons, je préfère généralement créer des fonctions avec defplutôt qu'avec lambda.

Salle Aaron
la source
6

Je suis d'accord avec le conseil de nosklo: si vous devez donner un nom à la fonction, utilisez def. Je réserve des lambdafonctions pour les cas où je ne fais que passer un bref extrait de code à une autre fonction, par exemple:

a = [ (1,2), (3,4), (5,6) ]
b = map( lambda x: x[0]+x[1], a )
Dan Lenski
la source
3
Dans la plupart des combinaisons de map / lambda, vous pouvez le remplacer par une compréhension de liste ou une fonction plus appropriée. Par exemple, "map (sum, a)" ou "[x [0] + x [1] for x in a]"
John Millikin
Oui c'est vrai. Parfois, je préfère map (). Il s'agissait principalement d'un exemple artificiel d'utilisation d'une fonction en ligne.
Dan Lenski
exactement ... La plupart des exemples sont artificiels, car leur utilisation n'est pas naturelle et il existe de meilleures façons pratiques dans la plupart des cas.
nosklo
5

Tout en étant d'accord avec les autres réponses, c'est parfois plus lisible. Voici un exemple où lambdaest très pratique, dans un cas d'utilisation je continue à rencontrer d'une N dimensions defaultdict.
Voici un exemple:

from collections import defaultdict
d = defaultdict(lambda: defaultdict(list))
d['Foo']['Bar'].append(something)

Je le trouve plus lisible que de créer un defpour la deuxième dimension. Ceci est encore plus significatif pour les dimensions supérieures.

Jonathan
la source
from functools import partial; defaultdict(partial(defaultdict, list)). Attribuez le partiel à un nom si vous souhaitez l'utiliser plusieurs fois. Mais, si vous continuez à rencontrer cette construction, cela signifie que vous n'êtes pas SEC. Factorisez-le dans une bibliothèque utilitaire. Vous pouvez utiliser cette construction pour créer un defaultdict arbitraire à n dimensions en utilisant d'autres functools (ou une boucle ou une récursivité).
DylanYoung
3

La principale utilisation de lambda a toujours été pour les fonctions de rappel simples et pour map, reduction, filter, qui nécessitent une fonction comme argument. Avec les compréhensions de liste devenant la norme, et l'ajout autorisé si comme dans:

x = [f for f in range(1, 40) if f % 2]

il est difficile d'imaginer un cas réel pour l'utilisation de lambda dans un usage quotidien. En conséquence, je dirais, évitez lambda et créez des fonctions imbriquées.

apg
la source
3

Une limitation importante des lambdas est qu'ils ne peuvent contenir rien d'autre qu'une expression. Il est presque impossible pour une expression lambda de produire autre chose que des effets secondaires triviaux, car elle ne peut pas avoir un corps aussi riche qu'une fonction def'ed.

Cela étant dit, Lua a influencé mon style de programmation vers l'utilisation intensive de fonctions anonymes, et j'en jette mon code. En plus de cela, j'ai tendance à penser à mapper / réduire comme des opérateurs abstraits d'une manière que je ne considère pas comme des compréhensions de listes ou des générateurs, presque comme si je reportais explicitement une décision d'implémentation en utilisant ces opérateurs.

Edit: C'est une question assez ancienne, et mes opinions sur la question ont quelque peu changé.

Tout d'abord, je suis fortement contre l'attribution d'une lambdaexpression à une variable; car python a une syntaxe spéciale juste pour cela (indice, def). En plus de cela, de nombreuses utilisations de lambda, même lorsqu'elles n'obtiennent pas de nom, ont des implémentations prédéfinies (et plus efficaces). Par exemple, l'exemple en question peut être abrégé en juste (1).__add__, sans qu'il soit nécessaire de l'envelopper dans un lambdaou def. De nombreux autres usages communs peuvent être satisfaits d' une combinaison des operator, itertoolset des functoolsmodules.

SingleNegationElimination
la source
1
(1).__add__- L'appel direct des méthodes dunder ne devrait presque jamais se produire. Mille lambdas pour chaque appel direct dunder.
Ethan Furman
1
@EthanFurman: Eh bien, d'après mon expérience, les appels de la nature (1).__add__sont quelque peu rares, mais je n'irais nulle part près de "devrait". sans aucun doute, je trouve que le premier est beaucoup plus lisible lambda x: 1 + x. Si nous avions quelque chose de plus proche de la notation par tranches de haskells, (1+)ce serait génial, mais nous devons nous contenter de ce qui est sémantiquement exactement cette chose, le nom de la méthode dunder.
SingleNegationElimination
2
  • Temps de calcul.
  • Fonction sans nom.
  • Pour réaliser une fonction et plusieurs, utilisez la fonctionnalité.

Considérant un exemple simple,

# CREATE ONE FUNCTION AND USE IT TO PERFORM MANY OPERATIONS ON SAME TYPE OF DATA STRUCTURE.
def variousUse(a,b=lambda x:x[0]):
    return [b(i) for i in a]

dummyList = [(0,1,2,3),(4,5,6,7),(78,45,23,43)]
variousUse(dummyList)                           # extract first element
variousUse(dummyList,lambda x:[x[0],x[2],x[3]]) # extract specific indexed element
variousUse(dummyList,lambda x:x[0]+x[2])        # add specific elements
variousUse(dummyList,lambda x:x[0]*x[2])        # multiply specific elements
bhargav patel
la source
1

Si vous allez simplement assigner le lambda à une variable dans la portée locale, vous pouvez également utiliser def car il est plus lisible et peut être développé plus facilement à l'avenir:

fun = lambda a, b: a ** b # a pointless use of lambda
map(fun, someList)

ou

def fun(a, b): return a ** b # more readable
map(fun, someList)
trop de php
la source
Les deux from operator import pow;map(pow, someList)et (a**b for a,b in someList)sont encore plus lisibles.
InQβ
1

Une utilisation des lambdas que j'ai trouvée ... est dans les messages de débogage.

Puisque les lambdas peuvent être évalués paresseusement, vous pouvez avoir un code comme celui-ci:

log.debug(lambda: "this is my message: %r" % (some_data,))

au lieu de peut-être cher:

log.debug("this is my message: %r" % (some_data,))

qui traite la chaîne de format même si l'appel de débogage ne produit pas de sortie en raison du niveau de journalisation actuel.

Bien sûr, pour que cela fonctionne comme décrit, le module de journalisation utilisé doit prendre en charge les lambdas en tant que "paramètres paresseux" (comme le fait mon module de journalisation).

La même idée peut être appliquée à tout autre cas d'évaluation paresseuse pour la création de valeur de contenu à la demande.

Par exemple, cet opérateur ternaire personnalisé:

def mif(condition, when_true, when_false):
    if condition:
         return when_true()
    else:
         return when_false()

mif(a < b, lambda: a + a, lambda: b + b)

au lieu de:

def mif(condition, when_true, when_false):
    if condition:
         return when_true
    else:
         return when_false

mif(a < b, a + a, b + b)

avec lambdas, seule l'expression sélectionnée par la condition sera évaluée, sans lambdas les deux seront évaluées.

Bien sûr, vous pouvez simplement utiliser des fonctions au lieu de lambdas, mais pour les expressions courtes, les lambdas sont (c) plus maigres.

Glushiator
la source
1
NB a loggingdéjà un formatage paresseux: log.debug("this is my message: %r", some_data)ne formatera que lorsque / si le message est demandé.
j08lue
@ La méthode lambda j08lue ignore l'évaluation de tout au cas où la sortie de débogage ne serait pas produite, dans le cas où vous montrez some_datapourrait être une expression coûteuse ou un appel de fonction / méthode.
Glushiator
0

Je suis d'accord avec nosklo. Au fait, même avec une utilisation une fois, jetez plupart du temps, vous voulez simplement utiliser quelque chose du module opérateur.

PAR EXEMPLE :

Vous avez une fonction avec cette signature: maFonction (données, fonction de rappel).

Vous voulez passer une fonction qui ajoute 2 éléments.

Utilisation de lambda:

myFunction(data, (lambda x, y : x + y))

La voie pythonique:

import operator
myFunction(data, operator.add)

Ou bien sûr, c'est un exemple simple, mais il y a beaucoup de choses que le module opérateur fournit, y compris les éléments setters / getters pour list et dict. Vraiment cool.

e-satis
la source
-1

Une différence majeure est que vous ne pouvez pas utiliser les deffonctions en ligne, ce qui est à mon avis le cas d'utilisation le plus pratique pour une lambdafonction. Par exemple lors du tri d'une liste d'objets:

my_list.sort(key=lambda o: o.x)

Je suggérerais donc de conserver l'utilisation des lambdas à ce genre d'opérations triviales, qui ne bénéficient pas non plus vraiment de la documentation automatique fournie par la dénomination de la fonction.

Ali Rasim Kocal
la source
-2

lambda est utile pour générer de nouvelles fonctions:

>>> def somefunc(x): return lambda y: x+y
>>> f = somefunc(10)
>>> f(2)
12
>>> f(4)
14
scrpy
la source