0
votes

Problème Python simple avec itération et Lambda

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 commentaires

Pourquoi vous attendez-vous à ce qu'il imprime 10 20 ? lst[1] vaut 2 et lst[2] vaut 3, donc il affichera 20 30 .


Faites attention à lst[i] . Vous avez défini i=0 mais ne l'avez pas imprimé. Dans le premier cas i=0 ce qui signifie 10*1


Le lambda ne capture pas la valeur de i au moment où il est créé. La valeur de i sera évaluée au moment où vous appelez f . Tout comme avec les fonctions def standard.


3 Réponses :


3
votes

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.


0 commentaires

1
votes

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)


0 commentaires

0
votes

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.


0 commentaires