Dictionary comprehension with lambda functions giv

2019-02-02 07:14发布

I tried the following code in Python 3.5.1:

>>> f = {x: (lambda y: x) for x in range(10)}
>>> f[5](3)
9

It's obvious that this should return 5. I don't understand where the other value comes from, and I wasn't able to find anything.

It seems like it's something related to reference - it always returns the answer of f[9], which is the last function assigned.

What's the error here, and how should this be done so that it works properly?

2条回答
Explosion°爆炸
2楼-- · 2019-02-02 07:41

Python scoping is lexical. A closure will refer to the name and scope of the variable, not the actual object/value of the variable.

What happens is that each lambda is capturing the variable x not the value of x.

At the end of the loop the variable x is bound to 9, therefore every lambda will refer to this x whose value is 9.

Why @ChrisP's answer works:

make_func forces the value of x to be evaluated (as it is passed into a function). Thus, the lambda is made with value of x currently and we avoid the above scoping issue.

def make_func(x):
    return lambda y: x

f = {x: make_func(x) for x in range(10)}
查看更多
地球回转人心会变
3楼-- · 2019-02-02 07:58

The following should work:

def make_func(x):
    return lambda y: x

f = {x: make_func(x) for x in range(10)}

The x in your code ends up referring to the last x value, which is 9, but in mine it refers to the x in the function scope.

查看更多
登录 后发表回答