lst = [1, 2, 3] i = 0 f = lambda x: x * lst[i] i = 1 print(f(10)) f = lambda x: x * lst[i] i = 2 print(f(10)) f = lambda x: x * lst[i] Above is my Python code and I thought it would print out 10, 20, but it says 20, 30. I don't understand why f is modified by i regardless of the explicit assignment. I've got to make it print 10, 20 using an iteration(actually the code is a simplified form of the original one), so it seems that f = lambda x: x * 1 is not allowed.
3 Réponses :
Je pense que vous vous attendez à ce que f = lambda x: x * lst[i]
stocke la valeur de i
, mais cela ne fonctionne pas de cette façon. Lorsqu'une fonction est définie, elle est juste stockée pour être utilisée plus tard, elle n'est pas évaluée lorsqu'elle est définie. Il n'est évalué que lorsqu'il est appelé.
Ainsi, lorsque vous appelez f(10)
pour la première fois, vous passez la valeur de x
comme 10 et l'interpréteur recherche la valeur de i
en mémoire, qui est 1
lors du premier appel de fonction et 2
lors du second appel de fonction. C'est pourquoi vous obtenez 20 30
en sortie.
N'hésitez pas à poser n'importe quelle question si vous avez encore des doutes.
i
est une variable globale. donc quand vous appelez f
il utilise la valeur actuelle de i
Regarder
10 20 30
production
f = lambda x: x * lst[i] lst = [1, 2, 3] for i in range(len(lst)): print(f(10))
Remarque, sans rapport avec votre question, mais f = lambda x: x * lst[i]
est contre les recommandations PEP8 :
Utilisez toujours une instruction
def
au lieu d'une instruction d'affectation qui lie une expression lambda directement à un identificateur:Correct:
def f(x): return 2*x
Mauvais:
f = lambda x: 2*x
La première forme signifie que le nom de l'objet fonction résultant est spécifiquement «f» au lieu du générique «». Ceci est plus utile pour les traces et les représentations sous forme de chaîne en général. L'utilisation de l'instruction d'affectation élimine le seul avantage qu'une expression lambda peut offrir par rapport à une instruction def explicite (c'est-à-dire qu'elle peut être intégrée dans une expression plus grande)
Imaginez l'expression lambda comme une véritable fonction, vous obtiendrez donc ce code:
lst = [1, 2, 3] i = 0 def f(x): return x * lst[i] i = 1 print(f(10)) # currently x=10 and i=1 def f(x): return x * lst[i] i = 2 print(f(10)) # currently x=10 and i=2 def f(x): return x * lst[i]
Je vois ce que tu veux dire. Dans votre tête, alors que vous définissez lambda x: x * lst[i]
, vous pensez que le nombre i
sera figé à ce moment - tout comme l'affectation. Lorsqu'il sera appelé plus tard, le nombre i
sera toujours la première valeur. Ce n'est pas vrai. La valeur de i
sera référencée lorsque vous appelez cette fonction.
Pourquoi vous attendez-vous à ce qu'il imprime
10 20
?lst[1]
vaut 2 etlst[2]
vaut 3, donc il affichera20 30
.Faites attention à
lst[i]
. Vous avez définii=0
mais ne l'avez pas imprimé. Dans le premier casi=0
ce qui signifie10*1
Le
lambda
ne capture pas la valeur dei
au moment où il est créé. La valeur dei
sera évaluée au moment où vous appelezf
. Tout comme avec les fonctionsdef
standard.