pythonarraysdeep-copyshallow-copy

Does the nums array make a deep copy of letters[2:5] = ['C', 'D', 'E']?


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?


Solution

  • 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.

    (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:

    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:

    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.