Search code examples
pythonlistparentoperationpropagation

Python: operation being unexpectedly propagated along parent lists


I am inserting and removing elements from a list that has been copied from another one I want to preserve unchanged. However, after applying the operations to the former, the later results also changed. How can I avoid that?

This is an example of what is happening:

a = range(11)

b = []

for i in a:
    b.append(i+1)

print b
#Out[10]: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]

c = b
# Here, what I expect is to safely save "b" and work on its copy.

c.insert(-1,10.5)

print c
#Out[13]: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 10.5, 11]

c.remove(11)
print c

#Out[15]: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 10.5]

# So far everything is right: I inserted and removed what I wanted.
# But then, when I check on my "backed-up b", it has been modified:

print b
#Out[16]: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 10.5]

# On the other hand, "a" remains the same; it seems the propagation does not affect
# "loop-parenthood":

print a
# Out[17]: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

I do not understand why the operation propagates over the parent list. How can I avoid that? Should I save the list as an arrange, or should I create the list copy by using a loop?


Solution

  • You need to make a deepcopy:

    import copy 
    
    a = range(11)
    
    b = []
    
    for i in a:
        b.append(i+1)
    
    print b
    #Out[10]: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
    
    c = copy.deepcopy(b)
    # Here, what I expect is to safely save "b" and work on its copy.
    
    c.insert(-1,10.5)
    
    print c
    #Out[13]: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 10.5, 11]
    
    c.remove(11)
    print c
    
    #Out[15]: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 10.5]
    
    # So far everything is right: I inserted and removed what I wanted.
    # But then, when I check on my "backed-up b", it has been modified:
    
    print b
    #Out[16]: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 10.5]
    
    # On the other hand, "a" remains the same; it seems the propagation do not affect
    # "loop-parenthood":
    
    print a
    

    Because without making a copy of the array, you are just creating a reference to the array. Here is how to use copy:

    http://docs.python.org/2/library/copy.html