I have some Python code that's dependent upon passing around some lambdas, and they get copied to a few different places, but I'm finding that when I pop them out of a list, they just magically disappear from all the other lists. I don't know if this is a bug or not. I'll note that I'm running this on CPython.

Here's some code to illustrate my point:

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)

If Python were doing reference counting, the new lists should increment the refcount, but the lambdas just keep disappearing.

I even tried this so that each time through the first loop a new instance of the lambda is created:

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 Answers
3

list.pop modifies the list in-place. So everyone with a reference to the list sees the same change. You're not storing copies in the second, you're just storing several references to one single list, which is then emptied in the first while loop.

You can copy lists through a[:] (which is a slice from the beginning to the end, including both) - note that it's a shallow copy - and nearly everything (including your own classes' instances) with the copy module.

The way you have your example setup, the only thing holding a reference to your lambdas is the listB. C holds a reference to listBnot to the lambdas inside of B. When you pop the lambdas out of B, no references to the lambda remain. What you are left with is C with the references to B which is now empty.