В чем разница между глубокой и мелкой копиями?



Обсудим это в контексте изменяемого объекта — списка. Для неизменяемых объектов глубокое и мелкое (поверхностное) копирование обычно не отличаются.



Рассмотрим три сценария.



I) Поставьте ссылку на исходный объект. Она отсылает новое имя li2 к тому же месту в памяти, на которое указывает li1. Поэтому любое изменение в li1 также происходит с li2:



li1 = [['a'],['b'],['c']]

li2 = li1



li1.append(['d'])

print(li2)

#=> [['a'], ['b'], ['c'], ['d']]




II) Создайте мелкую копию оригинала. Ее можно создать с помощью конструктора list() или mylist.copy().



Мелкая копия создает новый объект, но заполняет его ссылками на оригинал. Таким образом, добавление нового объекта в исходный список li3 не отразится в li4, а вот изменение объектов в li3 — отразится:



li3 = [['a'],['b'],['c']]

li4 = list(li3)



li3.append([4])

print(li4)

#=> [['a'], ['b'], ['c']]



li3[0][0] = ['X']

print(li4)

#=> [[['X']], ['b'], ['c']]




III) Создайте глубокую копию. Это делается с помощью copy.deepcopy(). Оригинал и копия полностью независимы, а изменения в одном не оказывают никакого влияния на другой:



import copy



li5 = [['a'],['b'],['c']]

li6 = copy.deepcopy(li5)



li5.append([4])

li5[0][0] = ['X']

print(li6)

#=> [['a'], ['b'], ['c']]




@python_job_interview