web-dev-qa-db-fra.com

Pourquoi utiliser les fonctions lambda?

Je peux trouver plein de choses qui me montrent ce qu'est une fonction lambda, comment la syntaxe fonctionne et ce qui ne fonctionne pas. Mais à part le "facteur de fraîcheur" (je peux créer une fonction au milieu d'un appel vers une autre fonction, c'est génial!), Je n'ai jamais vu quelque chose de très convaincant pour dire pourquoi j'ai vraiment besoin de l'utiliser.

Cela semble être davantage un choix stylistique ou structurel dans la plupart des exemples que j'ai vus. Et brise un peu la règle "Une seule façon correcte de faire quelque chose" dans la règle python. Comment cela rend-il mes programmes plus corrects, plus fiables, plus rapides ou plus faciles à comprendre? (La plupart des normes de codage que j'ai vues tendent à éviter les énoncés trop complexes sur une seule ligne. Si cela facilite la lecture, casser la lecture.)

58
NoMoreZealots

Voici un bon exemple:

def key(x):
    return x[1]

a = [(1, 2), (3, 1), (5, 10), (11, -3)]
a.sort(key=key)

versus

a = [(1, 2), (3, 1), (5, 10), (11, -3)]
a.sort(key=lambda x: x[1])

Sous un autre angle: les expressions lambda sont également appelées "fonctions anonymes" et sont très utiles dans certains paradigmes de programmation, notamment la programmation fonctionnelle, pour laquelle le lambda calcul a inspiré.

http://en.wikipedia.org/wiki/Lambda_calculus

27
JAB

La syntaxe est plus concise dans certaines situations, principalement lorsqu'il s'agit de map et al.

map(lambda x: x * 2, [1,2,3,4])

me semble mieux que:

def double(x):
    return x * 2

map(double, [1,2,3,4])

Je pense que le lambda est un meilleur choix dans cette situation car le def double semble presque déconnecté de la map qui l’utilise. De plus, je suppose que cela présente l’avantage supplémentaire que la fonction est jetée lorsque vous avez terminé.

Il ya un inconvénient de lambda qui limite son utilité en Python, à mon avis: les lambdas ne peuvent avoir qu’une expression (c’est-à-dire que vous ne pouvez pas avoir plusieurs lignes). Cela ne peut tout simplement pas fonctionner dans un langage qui impose des espaces.

De plus, chaque fois que j'utilise lambda, je me sens vraiment bien.

16
Donald Miner

Les fonctions Lambda sont particulièrement utiles pour des tâches telles que les fonctions de rappel ou les endroits dans lesquels vous avez besoin d’une fonction à jeter. L'exemple de JAB est parfait - il serait mieux accompagné du mot clé argument key, mais il fournit tout de même des informations utiles.

Quand

def key(x):
    return x[1]

apparaît à 300 lignes de 

[(1,2), (3,1), (5,10), (11,-3)].sort(key)

que fait la clé? Il n'y a vraiment aucune indication. Vous pouvez avoir une sorte de conjecture, en particulier si vous connaissez la fonction, mais il faut généralement revenir en arrière. OTOH,

[(1,2), (3,1), (5,10), (11,-3)].sort(lambda x: x[1])

vous en dit beaucoup plus.

  1. Sort prend une fonction comme argument
  2. Cette fonction prend 1 paramètre (et "retourne" un résultat)
  3. J'essaie de trier cette liste par la 2e valeur de chacun des éléments de la liste
  4. (Si la liste était une variable, vous ne pouviez pas voir les valeurs), cette logique s'attend à ce que la liste contienne au moins 2 éléments.

Il y a probablement plus d'informations, mais c'est déjà une quantité énorme que vous obtenez simplement en utilisant une fonction anonyme lambda au lieu d'une fonction nommée.

De plus, il ne pollue pas votre espace de noms;)

9
Wayne Werner

Pour moi, c'est une question d'expressivité du code. Lors de la rédaction d'un code que les utilisateurs devront prendre en charge, celui-ci doit raconter une histoire de manière aussi concise et facile à comprendre que possible. Parfois, l'expression lambda est plus compliquée, d'autres fois, elle indique plus directement ce que cette ligne ou ce bloc de code est en train de faire. Utilisez votre jugement lorsque vous écrivez.

Pensez-y comme à structurer une phrase. Quelles sont les parties importantes (noms et verbes par rapport aux objets et méthodes, etc.) et comment doivent-elles être ordonnées pour cette ligne ou ce bloc de code afin de transmettre ce que cela fait intuitivement.

7
David

Oui, vous avez raison - c'est un choix structurel. Cela ne rend probablement pas vos programmes plus corrects en utilisant simplement des expressions lambda. Cela ne les rend pas plus fiables, et cela n’a rien à voir avec la vitesse.

Il ne s'agit que de flexibilité et du pouvoir d'expression. Comme la compréhension de liste. Vous pouvez définir la plupart des fonctions nommées (éventuellement en polluant les espaces de noms, mais c’est là une question purement stylistique).

La lisibilité peut être facilitée par le fait que vous n'avez pas à définir une fonction nommée distincte, que quelqu'un d'autre devra trouver, lire et comprendre qu'il ne fait qu'appeler une méthode blah () sur son argument.

Cela peut être beaucoup plus intéressant lorsque vous l’utilisez pour écrire des fonctions qui créent et renvoient d’autres fonctions, où ce que font exactement ces fonctions dépend de leurs arguments. Cela peut constituer un moyen très concis et lisible de paramétrer le comportement de votre code. Vous pouvez simplement exprimer des idées plus intéressantes.

Mais cela reste un choix structurel. Vous pouvez le faire autrement. Mais il en va de même pour la programmation orientée objet;) 

5
Piotr Kalinowski

Ignorez un instant les détails qui sont spécifiquement anonymes les fonctions dont nous parlons. les fonctions, y compris anonymes, sont des quantités assignables (presque, mais pas vraiment, des valeurs) en Python. une expression comme

map(lambda y: y * -1, range(0, 10))

mentionne explicitement quatre quantités anonymes: -1, 0, 10 et le résultat de l'opérateur lambda, plus le résultat implicite de l'appel map. il est possible de créer des valeurs de types anonymes dans certaines langues. alors ignorez la différence superficielle entre les fonctions et les nombres. la question de savoir quand utiliser une fonction anonyme par opposition à une fonction nommée est semblable à celle de savoir quand insérer un littéral de nombre nu dans le code et quand déclarer un code TIMES_I_WISHED_I_HAD_A_PONY ou BUFFER_SIZE à l'avance il y a des moments où il est approprié d'utiliser un littéral (numérique, chaîne ou fonction), et d'autres fois, il est plus approprié de nommer une telle chose et de s'y référer par son nom.

voir par exemple. Le livre provocateur d'Allen Holub, qui suscite la réflexion ou la colère, sur les modèles de conception en Java; il utilise un peu les classes anonymes.

5
just somebody

Une utilisation de la fonction lambda que j’ai apprise, et où n’est pas une autre bonne alternative ou du moins me cherche le mieux, c’est l’action par défaut dans le paramètre de fonction de

parameter=lambda x: x

Cela renvoie la valeur sans modification, mais vous pouvez éventuellement fournir une fonction pour effectuer une transformation ou une action (comme imprimer la réponse, pas seulement renvoyer).

De plus, il est souvent utile d’utiliser le tri comme clé:

key=lambda x: x[field]

L'effet est de trier par élément de champ (élément de mémorisation basé sur zéro) de chaque élément en séquence. Pour inverser, vous n’avez pas besoin de lambda, car il est plus facile de l’utiliser.

reverse=True

Il est souvent presque aussi facile de créer de nouvelles fonctions réelles et de les utiliser à la place de lambda. Si des personnes ont beaucoup étudié la programmation LISP ou d’autres programmes fonctionnels, elles ont également une tendance naturelle à utiliser la fonction lambda, car dans LISP les définitions de fonctions sont gérées par le calcul lambda.

2
Tony Veijalainen

Les Lambda sont des objets, pas des méthodes, et ils ne peuvent pas être invoqués de la même manière que les méthodes sont .

succ = ->(x){ x+1 }

succ mow contient un objet Proc, que nous pouvons utiliser comme n'importe quel autre:

succ.call(2)

nous donne une sortie = 3

2
Akash Soti

Lambda, bien qu'utile dans certaines situations, présente un potentiel d'abus important. Les lambda rendent presque toujours le code plus difficile à lire. Et s'il peut sembler satisfaisant de placer tout votre code sur une seule ligne, ce sera nul pour la prochaine personne qui doit lire votre code.

En direct de PEP8

"L'une des idées clés de Guido est que le code est lu beaucoup plus souvent qu'il n'est écrit."

2
user297250

Dans certains cas, il est beaucoup plus clair d'exprimer quelque chose de simple comme un lambda. Envisagez un tri régulier ou un tri inversé, par exemple:

some_list = [2, 1, 3]
print sorted(some_list)
print sorted(some_list, lambda a, b: -cmp(a, b))

Pour ce dernier cas, écrire une fonction à part entière simplement pour renvoyer une -cmp(a, b) créerait plus de malentendu qu'un lambda. 

1
abbot

Les Lambdas sont des fonctions anonymes (fonction sans nom) pouvant être affectées à une variable ou transmises à une autre fonction en tant qu'argument. L'utilité de lambda sera réalisée lorsque vous aurez besoin d'un petit morceau de fonction à exécuter une par une ou plusieurs fois. Au lieu d'écrire la fonction dans la portée globale ou de l'inclure dans votre programme principal, vous pouvez ajouter quelques lignes de code, le cas échéant, à une variable ou à une autre fonction. De même, lorsque vous transmettez la fonction en tant qu'argument à une autre fonction pendant l'appel de la fonction, vous pouvez modifier l'argument (la fonction anonyme) afin de rendre la fonction elle-même dynamique. Supposons que si la fonction anonyme utilise des variables hors de son champ d'application, elle est appelée fermeture. Ceci est utile dans les fonctions de rappel.

1
Anupama V Iyengar

Je souhaite signaler une situation autre que le traitement de liste où les fonctions lambda semblent être le meilleur choix:

from tkinter import *
from tkinter import ttk        
def callback(arg):
    print(arg)
    pass
root = Tk()
ttk.Button(root, text = 'Button1', command = lambda: callback('Button 1 clicked')).pack()
root.mainloop()

Et si nous abandonnons la fonction lambda ici, le rappel ne peut l'exécuter qu'une seule fois.

ttk.Button(root, text = 'Button1', command = callback('Button1 clicked')).pack()
1
Henry.L

Un autre point est que python n'a pas d'instructions switch. La combinaison de lambdas avec des dict peut être une alternative efficace. par exemple.:

switch = {
 '1': lambda x: x+1, 
 '2': lambda x: x+2,
 '3': lambda x: x+3
}

x = starting_val
ans = expression
new_ans = switch[ans](x)
0
zzu

Il est bien vrai que l’abus des fonctions lambda conduit souvent à un code mauvais et difficile à lire. D'autre part, lorsqu'il est utilisé avec précision, il fait le contraire. Il y a déjà de bonnes réponses dans ce fil, mais un exemple que j'ai rencontré est:

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

square = power(2)
cubic = power(3)
quadruple = power(4)

print(square(10)) # 100
print(cubic(10)) # 1000
print(quadruple(10)) # 10000

Ce cas simplifié pourrait être réécrit de nombreuses autres manières sans utiliser lambda. Néanmoins, on peut en déduire comment les fonctions lambda peuvent améliorer la lisibilité et la réutilisation du code dans des cas et des fonctions plus complexes avec cet exemple.

0
Ongun Uzay Macar