Last Updated on 2021-10-05 by Clay
The most likely causes of programming error in Python is unexpected changes in the value fo List object. Many people have just encountered this problem, they may yell that Python is broken.
One of the simplest example is that the List object has been changed along with the assigned source:
# coding: utf-8 def main(): # Init a = [[1, 1], [2, 2]] b = a # Append a.append([3, 3]) # Print print('a:', a) print('b:', b) if __name__ == '__main__': main()
Output:
a: [[1, 1], [2, 2], [3, 3]]
b: [[1, 1], [2, 2], [3, 3]]
It’s weird, right? Obviously, the only variable that has added a new value is the variable a
!
The reason for this is actually simple, because b
is just a new variable name that shares the value of a
. We can use the id()
function to see:
# coding: utf-8 def main(): # Init a = [[1, 1], [2, 2]] b = a # Append a.append([3, 3]) # Print print('a id:', id(a)) print('b id:', id(b)) if __name__ == '__main__': main()
Output:
a id: 140219101052168
b id: 140219101052168
You will find that a
and b
are really the same value, but the variable names are different.
But this is troublesome.
Usually we don’t want to use two variables with the same value but different names. We hope that b can “copy” the value of a
. However, no matter how the value is increased or decreased in the future, both a
and b
are not related.
At this time, it is the turn of the copy
module in Python to debut.
Shallow Copy & Deep Copy
Python’s copy
module is divided into two types: shallow copy and deep copy.
shallow copy
Shallow copy uses the copy()
function to make the copied objects independent, that is, a
and b
are no longer relevant, and adding new values will not affect b
.
# coding: utf-8 import copy def main(): # Init a = [[1, 1], [2, 2]] b = copy.copy(a) # Change a.append([3, 3]) # Print print('a:', a) print('a id:', id(a)) print('='*50) print('b:', b) print('b id:', id(b)) if __name__ == '__main__': main()
Output:
a: [[1, 1], [2, 2], [3, 3]]
a id: 140378660764744
==================================================
b: [[1, 1], [2, 2]]
b id: 140378660765000
But shallow copying is still different from deep copying. That is to say, although the addition and deletion of elements in the a
variable will not affect b
, if the element b
in the a variable is directly changed, it will still affect b
.
# coding: utf-8 import copy def main(): # Init a = [[1, 1], [2, 2]] b = copy.copy(a) # Change a[0][0] = 0 # Print print('a:', a) print('a id:', id(a)) print('='*50) print('b:', b) print('b id:', id(b)) if __name__ == '__main__': main()
Output:
a: [[0, 1], [2, 2]]
a id: 140223083543624
==================================================
b: [[0, 1], [2, 2]]
b id: 140223083543880
As you can see, the first element of [1, 1] has been changed. To prevent this from happening, you can only use deepcopy()
.
deep copy
Deep copy uses the deepcopy()
function to completely separate the two variables a
and b
, which is a complete copy.
# coding: utf-8 import copy def main(): # Init a = [[1, 1], [2, 2]] b = copy.deepcopy(a) # Change a.append([3, 3]) a[0][0] = 0 # Print print('a:', a) print('a id:', id(a)) print('='*50) print('b:', b) print('b id:', id(b)) if __name__ == '__main__': main()
Output:
a: [[0, 1], [2, 2], [3, 3]]
a id: 140719924018248
==================================================
b: [[1, 1], [2, 2]]
b id: 140719924018504
As you can see, even if the elements in a
are modified this time, b
will not be affected.
References
- https://www.programiz.com/python-programming/shallow-deep-copy
- https://www.python-course.eu/deep_copy.php
- https://realpython.com/copying-python-objects/