相关疑难解决方法(0)

(lambda)函数闭包捕获了什么?

最近我开始玩Python,我遇到了一些特殊的闭包方式.请考虑以下代码:

adders=[0,1,2,3]

for i in [0,1,2,3]:
   adders[i]=lambda a: i+a

print adders[1](3)
Run Code Online (Sandbox Code Playgroud)

它构建了一个简单的函数数组,它接受单个输入并返回由数字添加的输入.函数在for循环中构造,迭代器i从中循环0到3.对于这些数字中的每一个,lambda都会创建一个函数i,该函数捕获并将其添加到函数的输入中.最后一行将第二个lambda函数3作为参数调用.令我惊讶的是输出结果是6.

我期待一个4.我的理由是:在Python中,一切都是一个对象,因此每个变量都是指向它的指针.在创建lambda闭包时i,我希望它存储一个指向当前指向的整数对象的指针i.这意味着当i分配一个新的整数对象时,它不应该影响先前创建的闭包.遗憾的是,adders在调试器中检查数组表明它确实存在.所有的lambda功能指的最后一个值i,3,这将导致adders[1](3)返回6.

这让我想知道以下内容:

  • 闭包捕获的内容是什么?
  • 什么是最优雅的方式来说服lambda函数以更改其值i时不会受到影响的方式捕获当前i值?

python lambda closures

237
推荐指数
5
解决办法
4万
查看次数

在循环中创建函数

我正在尝试在循环内创建函数并将它们存储在字典中.问题是字典中的所有条目似乎最终都映射到最后创建的函数.代码如下:

functions = []

for i in range(3):
    def f():
        return i

    # alternatively: f = lambda: i

    functions.append(f)
Run Code Online (Sandbox Code Playgroud)

这输出:

print([f() for f in functions])
# expected output: [0, 1, 2]
# actual output:   [2, 2, 2]
Run Code Online (Sandbox Code Playgroud)

知道为什么吗?

python function

79
推荐指数
2
解决办法
3万
查看次数

`x = 42 是怎么回事;x = lambda: x` 解析了吗?

我很惊讶这个断言失败了:

x = 42
x = lambda: x
assert x() == 42
Run Code Online (Sandbox Code Playgroud)

似乎x结束了递归指本身,这样x(),x()()等都是功能。

用于解析它的规则是什么,它记录在哪里?

顺便说一句(不出乎意料地给出了上面的内容), 的原始值x在 lambda 定义之后没有引用:

class X:
  def __del__(self): print('deleting')

x = X()
x = lambda: x  # 'deleting' is printed here
Run Code Online (Sandbox Code Playgroud)

python language-lawyer

47
推荐指数
3
解决办法
2772
查看次数

Python列表理解与lambdas

我正在运行Python 3.4.2,我对代码的行为感到困惑.我正在尝试创建一个可调用多项式函数列表,其程度越来越高:

bases = [lambda x: x**i for i in range(3)]
Run Code Online (Sandbox Code Playgroud)

但出于某种原因,它做到了这一点:

print([b(5) for b in bases])
# [25, 25, 25]
Run Code Online (Sandbox Code Playgroud)

为什么bases看起来似乎是列表理解中最后一个lambda表达式的列表,重复?

python lambda

19
推荐指数
1
解决办法
2819
查看次数

Python Lambda问题

这里发生了什么?我正在尝试创建一个函数列表:

def f(a,b):
    return a*b

funcs = []

for i in range(0,10):
    funcs.append(lambda x:f(i,x))
Run Code Online (Sandbox Code Playgroud)

这不符合我的期望.我希望列表的行为如下:

funcs[3](3) = 9
funcs[0](5) = 0
Run Code Online (Sandbox Code Playgroud)

但是列表中的所有函数似乎都是相同的,并且将固定值设置为9:

funcs[3](3) = 27
funcs[3](1) = 9

funcs[2](6) = 54
Run Code Online (Sandbox Code Playgroud)

有任何想法吗?

python lambda

15
推荐指数
3
解决办法
3689
查看次数

为什么map()和列表理解的结果不同?

以下测试失败:

#!/usr/bin/env python
def f(*args):
    """
    >>> t = 1, -1
    >>> f(*map(lambda i: lambda: i, t))
    [1, -1]
    >>> f(*(lambda: i for i in t)) # -> [-1, -1]
    [1, -1]
    >>> f(*[lambda: i for i in t]) # -> [-1, -1]
    [1, -1]
    """
    alist = [a() for a in args]
    print(alist)

if __name__ == '__main__':
    import doctest; doctest.testmod()
Run Code Online (Sandbox Code Playgroud)

换一种说法:

>>> t = 1, -1
>>> args = []
>>> for i in t:
...   args.append(lambda: i)
... …
Run Code Online (Sandbox Code Playgroud)

python closures list-comprehension generator-expression late-binding

11
推荐指数
2
解决办法
2264
查看次数

使用 lambda 函数进行列表理解

def multipliers():
    return [lambda x: i * x for i in range(4)]


print([m(1) for m in multipliers()]) # [3, 3, 3, 3]
Run Code Online (Sandbox Code Playgroud)

为什么不是[0, 1, 2, 3]?无法理解。那么,出于某种原因,我们i = 3在所有 lambda 表达式中都有?为什么?

python

3
推荐指数
1
解决办法
4747
查看次数

如何使用理解列表创建包含lambda表达式的字典?

我正在尝试生成(类似)以下字典:

funcs1 = {
    '0':lambda x:x==0,
    '1':lambda x:x==1,
    '2':lambda x:x==2,
    '3':lambda x:x==3,
    '4':lambda x:x==4,
    '5':lambda x:x==5,
}
Run Code Online (Sandbox Code Playgroud)

我尝试用这样的列表理解创建字典:

funcs2 = {str(i):lambda x:x==i for i in range(0,6)}
Run Code Online (Sandbox Code Playgroud)

或者只是使用for循环:

funcs3 = {}
for i in range(0,6):
    funcs3.update({str(i): lambda x:x==i})
Run Code Online (Sandbox Code Playgroud)

但是,funcs2并且funcs3不一样funcs1,例如,当调用'0'每个元素并应用它时0,结果是不同的:

funcs1['0'](0)
Out[2]: True

funcs2['0'](0)
Out[3]: False

funcs3['0'](0)
Out[4]: False
Run Code Online (Sandbox Code Playgroud)

有人可以帮助我,并指出我在哪里犯了错误?

python lambda dictionary list-comprehension

2
推荐指数
1
解决办法
38
查看次数