I thought i knew Python until tonight. What is the correct way to do something like this? Here's my code:
a = ["one", "two", "three"]
b = a # here I want a complete copy that when b is changed, has absolutely no effect on a
b.append["four"]
print a # a now has "four" in it
Basically i want to know, instead of the b = a
step, how would I correctly make a copy of a list or dictionary so that when b
is changed a
does not change along with it?
What you are experiencing is the concept of references. All objects in Python have a reference and when you assign one to two names a
and b
, this results in both a
and b
pointing to the same object.
>>> a = range(3)
>>> b = a # same object
>>> b.append(3)
>>> a, b # same contents
([0, 1, 2, 3], [0, 1, 2, 3])
With lists, you can make create a new list b
that is a copy of another a
using b = a[:]
.
>>> a = range(3)
>>> b = a[:] # make b a new copy of a
>>> b.append(3)
>>> a, b # a is left unchanged
([0, 1, 2], [0, 1, 2, 3])
For a more general solution for any object, use the copy module. A shallow copy will copy the references stored within the object you're copying, whereas a deep copy will recursively make new copies of all objects.
>>> a = [range(2), range(3)]
>>> b = copy.copy(a) # shallow copy of a, equivalent to a[:]
>>> b[0] = range(4)
>>> a, b # setting an element of b leaves a unchanged
([[0, 1], [0, 1, 2]], [[0, 1, 2, 3], [0, 1, 2]])
>>> b[1].append(3)
>>> a, b # modifying an element of b modifies the element in a
([[0, 1], [0, 1, 2, 3]], [[0, 1, 2, 3], [0, 1, 2, 3]])
>>> a = [range(2), range(3)]
>>> b = copy.deepcopy(a) # deep recursive copy of a
>>> b[1].append(3)
>>> a, b # modifying anything in b leaves a unchanged
([[0, 1], [0, 1, 2]], [[0, 1], [0, 1, 2, 3]])
The correct way of copying an object is
from copy import copy
a = [1, 2, 3]
b = copy(a)
Pretty simple. There is shortcuts for lists:
a = [1, 2, 3]
b = a[:]
There is also deepcopy() if you want to copy the objects in the list as well.
Here are 3 ways to make a copy of list a
:
Use slice notation:
copy_of_a = a[:]
Use the list constructor:
copy_of_a = list(a)
Use the copy module:
from copy import copy
copy_of_a = copy(a)
These are all shallow copies, which is sufficient for your question. To learn about the difference between shallow copy and deep copy read the documentation of the copy module.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With