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
defau lieu d'une instruction d'affectation qui lie une expression lambda directement à un identificateur:Correct:
def f(x): return 2*xMauvais:
f = lambda x: 2*xLa 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=0mais ne l'avez pas imprimé. Dans le premier casi=0ce qui signifie10*1Le
lambdane capture pas la valeur deiau moment où il est créé. La valeur deisera évaluée au moment où vous appelezf. Tout comme avec les fonctionsdefstandard.