ГІСТ, який потрібно взяти, такий: спрацьовування з неглибокими списками (немає під-списків, лише окремі елементи) за допомогою "нормального призначення" викликає "побічний ефект", коли ви створюєте неглибокий список, а потім створюєте копію цього списку за допомогою "звичайного призначення" . Цей "побічний ефект" - це коли ви змінюєте будь-який елемент створеного списку копій, оскільки він автоматично змінить ті самі елементи вихідного списку. Це copy
стане в нагоді, оскільки воно не змінить оригінальні елементи списку при зміні елементів копіювання.
З іншого боку, copy
чи має "побічний ефект", коли у вас є список, який містить списки в ньому (під-списки), і deepcopy
вирішує його. Наприклад, якщо ви створюєте великий список із вкладеними списками в ньому (під-списки), і ви створюєте копію цього великого списку (оригінальний список). "Побічний ефект" виникає, коли ви змінюєте під-списки списку копій, які автоматично змінюють під-списки великого списку. Іноді (в деяких проектах) ви хочете зберегти великий список (ваш оригінальний список) таким, який він є без змін, і все, що вам потрібно, - це зробити копію його елементів (під-списків). Для цього ваше рішення полягає в тому, щоб скористатися deepcopy
цим "побічним ефектом" і зробити копію, не змінюючи оригінальний вміст.
Різне поведінка copy
та deep copy
операції стосуються лише складних об'єктів (тобто об'єктів, що містять інші об'єкти, такі як списки).
Ось відмінності, проілюстровані в цьому простому прикладі коду:
Перший
давайте перевіримо, як copy
поводиться (неглибоко), створивши оригінальний список та копію цього списку:
import copy
original_list = [1, 2, 3, 4, 5, ['a', 'b']]
copy_list = copy.copy(original_list)
Тепер давайте проведемо кілька print
тестів і подивимося, як поводиться оригінальний список порівняно зі списком його копій:
original_list та copy_list мають різні адреси
print(hex(id(original_list)), hex(id(copy_list))) # 0x1fb3030 0x1fb3328
елементи original_list та copy_list мають однакові адреси
print(hex(id(original_list[1])), hex(id(copy_list[1]))) # 0x537ed440 0x537ed440
підменю елементів original_list та copy_list мають однакові адреси
print(hex(id(original_list[5])), hex(id(copy_list[5]))) # 0x1faef08 0x1faef08
зміна елементів original_list НЕ змінює елементи copy_list
original_list.append(6)
print("original_list is:", original_list) # original_list is: [1, 2, 3, 4, 5, ['a', 'b'], 6]
print("copy_list is:", copy_list) # copy_list is: [1, 2, 3, 4, 5, ['a', 'b']]
зміна елементів copy_list НЕ змінює елементи original_list
copy_list.append(7)
print("original_list is:", original_list) # original_list is: [1, 2, 3, 4, 5, ['a', 'b'], 6]
print("copy_list is:", copy_list) # copy_list is: [1, 2, 3, 4, 5, ['a', 'b'], 7]
зміна оригінального_подмета_елементів автоматично модифікує під_елементи copy_list
original_list[5].append('c')
print("original_list is:", original_list) # original_list is: [1, 2, 3, 4, 5, ['a', 'b', 'c'], 6]
print("copy_list is:", copy_list) # copy_list is: [1, 2, 3, 4, 5, ['a', 'b', 'c'], 7]
зміна під_елементів copy_list автоматично змінює под_елементи original_list
copy_list[5].append('d')
print("original_list is:", original_list) # original_list is: [1, 2, 3, 4, 5, ['a', 'b', 'c', 'd'], 6]
print("copy_list is:", copy_list) # copy_list is: [1, 2, 3, 4, 5, ['a', 'b', 'c', 'd'], 7]
Друге
давайте перевіримо, як deepcopy
поводиться, зробивши те саме, що ми зробили copy
(створивши оригінальний список та копію цього списку):
import copy
original_list = [1, 2, 3, 4, 5, ['a', 'b']]
copy_list = copy.copy(original_list)
Тепер давайте проведемо кілька print
тестів і подивимося, як поводиться оригінальний список порівняно зі списком його копій:
import copy
original_list = [1, 2, 3, 4, 5, ['a', 'b']]
copy_list = copy.deepcopy(original_list)
original_list та copy_list мають різні адреси
print(hex(id(original_list)), hex(id(copy_list))) # 0x1fb3030 0x1fb3328
елементи original_list та copy_list мають однакові адреси
print(hex(id(original_list[1])), hex(id(copy_list[1]))) # 0x537ed440 0x537ed440
підменю елементів original_list та copy_list мають різні адреси
print(hex(id(original_list[5])), hex(id(copy_list[5]))) # 0x24eef08 0x24f3300
зміна елементів original_list НЕ змінює елементи copy_list
original_list.append(6)
print("original_list is:", original_list) # original_list is: [1, 2, 3, 4, 5, ['a', 'b'], 6]
print("copy_list is:", copy_list) # copy_list is: [1, 2, 3, 4, 5, ['a', 'b']]
зміна елементів copy_list НЕ змінює елементи original_list
copy_list.append(7)
print("original_list is:", original_list) # original_list is: [1, 2, 3, 4, 5, ['a', 'b'], 6]
print("copy_list is:", copy_list) # copy_list is: [1, 2, 3, 4, 5, ['a', 'b'], 7]
зміна original_list sub_elements НЕ змінює copy_list sub_elements
original_list[5].append('c')
print("original_list is:", original_list) # original_list is: [1, 2, 3, 4, 5, ['a', 'b', 'c'], 6]
print("copy_list is:", copy_list) # copy_list is: [1, 2, 3, 4, 5, ['a', 'b'], 7]
зміна sub_elements copy_list НЕ змінює под_елементи original_list
copy_list[5].append('d')
print("original_list is:", original_list) # original_list is: [1, 2, 3, 4, 5, ['a', 'b', 'c', 'd'], 6]
print("copy_list is:", copy_list) # copy_list is: [1, 2, 3, 4, 5, ['a', 'b', 'd'], 7]