Capturer des variables dans des fonctions anonymes en Python

Vous avez défini une fonction anonyme en utilisant le mot-clé lambda, mais vous devez également capturer les valeurs de certaines variables au moment de leur définition. Considérez le comportement du code suivant:

>>> x = 10
>>> a = lambda y: x + y
>>> x = 20
>>> b = lambda y: x + y
>>>

Maintenant, posez-vous une question. Quelles sont les valeurs de a(10) et b(10)? Si vous pensez que les résultats pourraient être 20 et 30, vous n’auriez pas raison:

>>> a(10)
30
>>> b(10)
30
>>>

Le problème ici est que la valeur de x utilisée dans l’expression lambda est une variable libre qui est définie au moment de l’exécution et non au moment de la définition.

Ainsi, la valeur de x dans les expressions lambda est quelle que soit la valeur de la variable x au moment de l’exécution. Par exemple:

>>> x = 15
>>> a(10)
25
>>> x = 3
>>> a(10)
13
>>>

Si vous voulez qu’une fonction anonyme capture une valeur au moment de la définition et la conserve, incluez la valeur comme valeur par défaut, comme ceci:

>>> x = 10
>>> a = lambda y, x=x: x + y
>>> x = 20
>>> b = lambda y, x=x: x + y
>>> a(10)
20
>>> b(10)
30
>>>

Le problème abordé dans cet article est quelque chose qui a tendance à apparaître dans le code qui essaie d’être un peu trop intelligent avec l’utilisation des fonctions lambda.

Par exemple, créer une liste d’expressions lambda à l’aide d’une compréhension de liste ou dans une boucle quelconque et s’attendre à ce que les fonctions lambda mémorisent la variable itérative au moment de la définition. Par exemple:

>>> mafct = [lambda x: x+n for n in range(5)]
>>> for f in mafct:
...     print(f(0))
...
4
4
4
4
4
>>>

Remarquez comment toutes les fonctions pensent que n a la dernière valeur pendant l’itération. Maintenant, comparez avec ce qui suit:

>>> mafct = [lambda x, n=n: x+n for n in range(5)]
>>> for f in mafct:
...     print(f(0))
...
0
1
2
3
4
>>>

Comme vous pouvez le voir, les fonctions capturent maintenant la valeur de n au moment de la définition.

LAISSER UN COMMENTAIRE

Please enter your comment!
Please enter your name here