Creating lambdas inside generator expression

Antoon Pardon antoon.pardon at vub.be
Wed Jun 29 14:47:29 EDT 2022


Or you could try this as an alternative:

conds = [ (lambda code: lambda msg: msg.hascode(code))(z) for z in 
("foo", "bar") ]


Op 29/06/2022 om 12:43 schreef Johannes Bauer:
> Aha!
>
> conds = [ lambda msg, z = z: msg.hascode(z) for z in ("foo", "bar") ]
>
> Is what I was looking for to explicitly use the value of z. What a
> caveat, didn't see that coming.
>
> Learning something new every day.
>
> Cheers,
> Joe
>
>
> Am 29.06.22 um 11:50 schrieb Johannes Bauer:
>> Hi list,
>>
>> I've just encounted something that I found extremely unintuitive and
>> would like your feedback. This bit me *hard*, causing me to question my
>> sanity for a moment. Consider this minimal example code (Py 3.10.4 on
>> Linux x64):
>>
>>
>> class Msg():
>> 	def hascode(self, value):
>> 		print("Check for", value)
>> 		return False
>>
>> conds = [
>> 	lambda msg: msg.hascode("foo"),
>> 	lambda msg: msg.hascode("bar"),
>> ]
>>
>> msg = Msg()
>> print(conds[0](msg))
>> print(conds[1](msg))
>>
>>
>>
>> It works perfectly and does exactly what it looks like. The output is:
>>
>> Check for foo
>> False
>> Check for bar
>> False
>>
>> But now consider what happens when we create the lambdas inside a list
>> comprehension (in my original I used a generator expresison, but the
>> result is the same). Can you guess what happens when we create conds
>> like this?
>>
>> conds = [ lambda msg: msg.hascode(z) for z in ("foo", "bar") ]
>>
>> I certainly could not. Here's what it outputs:
>>
>> Check for bar
>> False
>> Check for bar
>> False
>>
>> I.e., the iteration variable "z" somehow gets bound inside the lambda
>> not by its value, but by its reference. All checks therefore refence
>> only the last variable.
>>
>> This totally blew my mind. I can understand why it's happening, but is
>> this the behavior we would expect? And how can I create lambdas inside a
>> generator expression and tell the expression to use the *value* and not
>> pass the "z" variable by reference?
>>
>> Cheers,
>> Joe



More information about the Python-list mailing list