What is the difference between shallow copy, deepcopy and normal assignment operation?
Normal assignment operations will simply point the new variable towards the existing object. The docs explain the difference between shallow and deep copies:
The difference between shallow and deep copying is only relevant for
compound objects (objects that contain other objects, like lists or
class instances):
A shallow copy constructs a new compound object and then (to the extent possible) inserts references into it to the objects found in the original.
A deep copy constructs a new compound object and then, recursively, inserts copies into it of the objects found in the
original.
Here's a little demonstration:
import copy
a = [1, 2, 3]
b = [4, 5, 6]
c = [a, b]
Using normal assignment operatings to copy:
d = c
print id(c) == id(d) # True - d is the same object as c
print id(c[0]) == id(d[0]) # True - d[0] is the same object as c[0]
Using a shallow copy:
d = copy.copy(c)
print id(c) == id(d) # False - d is now a new object
print id(c[0]) == id(d[0]) # True - d[0] is the same object as c[0]
Using a deep copy:
d = copy.deepcopy(c)
print id(c) == id(d) # False - d is now a new object
print id(c[0]) == id(d[0]) # False - d[0] is now a new object
What is the difference between a deep copy and a shallow copy?
Shallow copies duplicate as little as possible. A shallow copy of a collection is a copy of the collection structure, not the elements. With a shallow copy, two collections now share the individual elements.
Deep copies duplicate everything. A deep copy of a collection is two collections with all of the elements in the original collection duplicated.
Mutable and Inmutable Deep/Shallow copies Python
TL;DR
- Shallow copy makes a copy of the outer level items in the list, whatever nested inside those items will still be copied by reference
- Deep copy goes through all nested items and copies each single one of them
Your example doesn't include copying, a = b
will have both variables point to the same list.
Consider the following examples:
a = [[1, 2, 3], [4, 5, 6]]
b = copy.copy(a) # shallow copy, you can use b = list(a) too
a[0][0] = 5
# b[0][0] will be 5
a[0] = [0, 0]
# b[0] will not change
Why? Because shallow copy produces a copy of the elements in the list in the first level (b[0]
is a copy of a[0]
) but if a[0]
is a list, anything inside that list is pointing to the same place as the elements in b[0]
.
While deep copy keeps going and copying all the elements no matter how nested the elements are
a = [[1, 2, 3], [4, 5, 6]]
b = copy.deepcopy(a) # deep copy
a[0][0] = 5
# b[0][0] will not change
a[0] = [0, 0]
# b[0] will not change
Is copy.copy different from assignment in python
All python variables are bindings to some objects in memory.
- Does this code do anything?
Yes, it does.
Actually it creates a new object in memory with new name.
- How does
copy.copy(node
) differ fromnode = node
?
By assignment you are getting different names for the same object.
So if you are really need a copy
you should use shallow
or deep
copy.
Example:
>>> x = [1]
>>> id(x)
35964488
>>> y = x
>>> id(y)
35964488
>>> z = x[:]
>>> id(z)
35964768
So x
and y
have same id
, while z
has different.
Same here:
>>> import copy
>>> c = copy.copy(x)
>>> id(c)
35985168
>>> id(x)
35964488
Quote from docs about shallow
and deep
copy:
The difference between shallow and deep copying is only relevant for
compound objects (objects that contain other objects, like lists or
class instances):A shallow copy constructs a new compound object and then (to the extent possible) inserts references into it to the objects found in
the original.A deep copy constructs a new compound object and then, recursively, inserts copies into it of the objects found in the
original.
Shallow/Deep copy in python
A shallow copy creates a new list object and copies across all the references contained in the source list. A deep copy creates new objects recursively.
You won't see the difference with just immutable contents. Use nested lists to see the difference:
>>> import copy
>>> a = ['foo', 'bar', 'baz']
>>> b = ['spam', 'ham', 'eggs']
>>> outer = [a, b]
>>> copy_of_outer = copy.copy(outer)
>>> outer is copy_of_outer
False
>>> outer == copy_of_outer
True
>>> outer[0] is a
True
>>> copy_of_outer[0] is a
True
>>> outer[0] is copy_of_outer[0]
True
A new copy of the outer list was created, but the contents of the original and the copy are still the same objects.
>>> deep_copy_of_outer = copy.deepcopy(outer)
>>> deep_copy_of_outer[0] is a
False
>>> outer[0] is deep_copy_of_outer[0]
False
The deep copy doesn't share contents with the original; the a
list has been recursively copied as well.
Related Topics
How to Keep Keys/Values in Same Order as Declared
How Is Returning the Output of a Function Different from Printing It
How to Sort a List of Dictionaries by a Value of the Dictionary
Import Multiple CSV Files into Pandas and Concatenate into One Dataframe
How to Get Posted Json in Flask
Tkinter Assign Button Command in a For Loop With Lambda
Limiting Floats to Two Decimal Points
Why Is the Output of My Function Printing Out "None"
How to Access Object Attribute Given String Corresponding to Name of That Attribute
How to Add Sequential Counter Column on Groups Using Pandas Groupby
Find All Files in a Directory With Extension .Txt in Python
How to Read/Process Command Line Arguments
Python Ftp Get the Most Recent File by Date