770

Поверхневе та глибоке копіювання в Python

Копіювання в Python

При розробці програмного забезпечення програмістам часто доводиться працювати з операцією копіювання об'єктів. Це допомагає оптимізувати код, реалізувати складні функції і загалом підвищує обчислювальну ефективність програми. Однак, при копіюванні вкладених списків і словників програміста може чекати неочевидний сюрприз, коли різні змінні зв'язуються з тими самими осередками пам'яті. Таким чином, при зміні однієї такої змінної змінюються і всі інші, які були з нею пов'язані.

Щоб результат копіювання став прогнозованим та зрозумілим, у мові Python модуль copy надає дві різні операції копіювання – поверхневе та глибоке. У цій статті ми розберемо принцип роботи кожного з них, а для більшої наочності використовуємо приклади.

Поверхневе копіювання

Операція поверхневого копіювання створює новий об'єкт, який є точною копією вихідного, але з одним застереженням — всі вкладені елементи нового об'єкта міститимуть лише посилання адреси пам'яті оригінальних елементів.

Таким чином ми отримуємо два взаємопов'язані об'єкти, і внесення змін до будь-якої з них миттєво позначиться на іншому.

Для того, щоб подивитися як це працює на практиці, створимо масив, що містить вкладений список, а потім зробимо його копію за допомогою методу copy:

>>> sublist = []
>>> outer_list = [42, 73, sublist]
>>> copy_list = outer_list.copy()

Тепер переконаємося в тому, що у нас вийшло два різні об'єкти. Для цього:

>>> copy_list is outler_list
False
>>> copy_list[0] = 0
>>> outler_list     # Не повлияло на исходный
[42, 73, []]

Як бачимо, зараз все працює передбачувано, і навіть внесення коригувань у copy_list ніяк не відбивається на outer_list. Однак, якщо ми захочемо відредагувати вкладений список sublist — зміни торкнуться оригінального та скопійованого об'єкта:

>>> sublist.append (999)
>>> copy_list
[0, 73,  [999]]
>>> outer_list
[42, 73,  [999]]

Таке копіювання у мові програмування Python називається поверхневим.

Якщо розглянути ситуацію глибше, то насправді модифікація sublist не торкається вмісту самих об'єктів copy_list і outer_list. Просто цей елемент відноситься до іншої комірки пам'яті, яку можна змінювати незалежно від них.

Глибоке копіювання

Можливості поверхневого копіювання широко використовуються в розробці, але іноді потрібно створити повністю незалежну копію об'єкта, щоб робота з нею ніяк не торкалася оригінального примірника. Для цього Python використовується глибоке копіювання.

Метод глибокого копіювання в чомусь схожий з рекурсивним алгоритмом: спочатку копіюються елементи першого рівня вкладеності, потім, якщо було знайдено об'єкт, що змінюється, копіюється його вміст і так далі. В результаті ми отримаємо новий, абсолютно незалежний об'єкт, який знаходиться в окремому осередку пам'яті.

Щоб подивитися як це працює на практиці, створимо список із двома рівнями вкладеності:

>>> a = [1, [2, [3, 4], 5], 6]
>>> a
[1, [2, [3, 4], 5], 6]

Далі, щоб виконати глибоке копіювання, імпортуємо модуль copy. Для цього в коді пишемо такий рядок:

>>> import copy

Тепер можемо виконати безпосередньо копіювання:

>>> b = copy.deepcopy (a)

Після виконання глибокого копіювання модифікація змінної на будь-якому рівні вкладеності одного об'єкта ніяк не позначиться на іншому. Спробуємо зробити таку операцію у коді та подивимося на результат:

>>> a[0] = 111
>>> a[1][0] = 222
>>> a[1][1][0] = 333
>>>
>>> a
[111, [222, [333, 4], 5], 6]
>>>
>>>
>>> b
[1, [2, [3, 4], 5], 6]

Де вивчати мову Python

Python — це одна з найбільш популярних мов програмування, що підтримується Google. Якщо ви хочете опанувати професію Python-розробника, приєднуйтесь до безкоштовних курсів у лабораторії SpaceLAB. У нас ви зможете пройти навчання на реальних проектах під кураторством досвідчених менторів. Найбільш успішні студенти матимуть можливість працевлаштування в AVADA MEDIA — одну з найкращих IT-компаній України.