为什么我的lambdas消失了?

时间:2011-04-08 19:26:10

标签: python arrays arraylist lambda

我有一些Python代码依赖于传递一些lambda,并且它们被复制到几个不同的地方,但是我发现当我从列表中弹出它们时,它们只是神奇地从所有其他列表中消失。我不知道这是不是一个bug。我会注意到我在CPython上运行它。

以下是一些代码来说明我的观点:

a = lambda x: x+x*3
b = []
c = []

for i in range(3):
    b.append(a)

for i in range(3):
    c.append(b)

while b:
    print b.pop()(5)

for d in c:
    while d:
        print d.pop()(10)

如果Python正在进行引用计数,那么新列表应该增加引用计数,但lambdas只是不断消失。

我甚至试过这个,以便每次通过第一个循环创建一个新的lambda实例:

b = []
c = []

for i in range(3):
    b.append(lambda x: x+x*3)

for i in range(3):
    c.append(b)

while b:
    print b.pop()(5)

for d in c:
    while d:
        print d.pop()(10)

仍然没有。

任何人都知道这里发生了什么?

3 个答案:

答案 0 :(得分:4)

list.pop就地修改列表。因此,每个参考该列表的人都会看到相同的变化。你不是在第二个存储副本,你只是将几个引用存储到一个列表中,然后在第一个while循环中清空。

您可以通过a[:]复制列表(这是从开头到结尾的切片,包括两者) - 请注意它是shallow copy - 几乎所有内容(包括您自己的类的实例)使用copy模块。

答案 1 :(得分:2)

您进行示例设置的方式,唯一引用lambdas的{​​{1}} listBC内的lambdas提及list B 。当您从B中弹出lambda时,不会保留对lambda的引用。您剩下的是B,其中C的引用现在为空。


此外,另一个答案的评论中指出了一个很好的提示:

信用:Dfan

  

如果要附加b的副本   c,你可以说c.append(b [:])

答案 2 :(得分:1)

import copy
for i in range(3):
    b.append(copy.deepcopy(a))
for i in range(3):
    c.append(copy.deepcopy(b))

您只是创建引用(浅层复制),以真正复制您希望必须使用“深层复制”的值。