I am learning shallow v.s. deep copying a list in Python. I learned that there're two ways to create copies that have the original values unchanged and only modify the new values or vice versa. They're shallow copy and deep copy.
Besides Copy.copy() and Copy.deepcopy(), I learned slice operators can be use for shallow and deep copying a list. From the Python official documentation, I was able to find information that doing correct_rgba = rgba[:]
, correct_rgba
makes a shallow copy of rgba
.
Example 1.
rgba = ["Red", "Green", "Blue", "Alph"]
correct_rgba = rgba[:]
correct_rgba[-1] = "Alpha"
correct_rgba # ["Red", "Green", "Blue", "Alpha"]
rgba # ["Red", "Green", "Blue", "Alph"]
However, I couldn't find information to confirm whether Assignment to Slices
is a deep copy. Here is an example found on the same Python documentation.
Example 2.
letters = ['a', 'b', 'c', 'd', 'e', 'f', 'g']
letters[2:5] = ['C', 'D', 'E']
letters # ['a', 'b', 'C', 'D', 'E', 'f', 'g']
letters[:] = []
letters # []
My questions:
(1) Does letters[2:5] deep copy ['C', 'D', 'E']? Does letters[:] deep copy []?
(2) How do I test to find out whether a list is a shallow or deep copy?
Let's break down your questions and concerns:
(1) Does letters[2:5]
deep copy ['C', 'D', 'E']
? Does letters[:]
deep copy []
?
No, neither of these operations performs a deep copy.
letters[2:5] = ['C', 'D', 'E']
is an assignment to a slice of the original list. It replaces the elements at indices 2, 3, and 4 with the new values, but it doesn't create a new copy of the list. The original list is modified in place.letters[:] = []
is also an assignment to a slice, but this time it replaces the entire list with an empty list. Again, this modifies the original list, it doesn't create a new copy.(2) How do I test to find out whether a list is a shallow or deep copy?
To determine whether a list is a shallow or deep copy, you can use the following methods:
Shallow copy:
id()
function to check if the original list and the copied list have the same memory address. If they do, it's a shallow copy.Example:
original_list = [[1, 2], [3, 4]]
shallow_copy = original_list[:]
print(id(original_list) == id(shallow_copy)) # True
original_list[0][0] = 10
print(shallow_copy) # [[10, 2], [3, 4]] (affected by original list)
Deep copy:
id()
function to check if the original list and the copied list have different memory addresses. If they do, it might be a deep copy.Example:
import copy
original_list = [[1, 2], [3, 4]]
deep_copy = copy.deepcopy(original_list)
print(id(original_list) != id(deep_copy)) # True
original_list[0][0] = 10
print(deep_copy) # [[1, 2], [3, 4]] (not affected by original list)
Keep in mind that these methods are not foolproof, and there might be edge cases where they don't accurately determine whether a copy is shallow or deep. However, they should give you a good indication in most cases.