Jak skopiować listę w Pythonie (płytka i głęboka kopia)

Dowiedz się, jak skopiować listę w Pythonie. Poznaj dzielenie list, metodę copy(), konstruktory list i opanuj różnicę między płytkimi i głębokimi kopiami.

Wypróbuj to rozwiązanie w Edytorze

Przegląd

W Pythonie listy są obiektami, które można modyfikować, a zmienne przechowują w pamięci odniesienia do tych obiektów, a nie rzeczywiste wartości. Oznacza to, że jeśli przypiszesz listę do nowej zmiennej (np. `lista_b = lista_a`), obie zmienne odwołują się do dokładnie tej samej listy. Wszelkie modyfikacje dokonane za pomocą `list_b` będą miały natychmiastowy wpływ na `list_a`. Aby uniknąć tego efektu ubocznego, należy utworzyć jawną kopię listy.

Python udostępnia kilka sposobów tworzenia płytkiej kopii listy. Płytka kopia tworzy nową listę zawierającą odniesienia do elementów znalezionych na oryginalnej liście. Typowe metody obejmują użycie wbudowanej metody listy `.copy()`, użycie dzielenia listy `list_a[:]` lub przekazanie listy do konstruktora `list()`. Wszystko to tworzy nowy kontener list, umożliwiający niezależne dodawanie i usuwanie elementów.

Jeśli jednak lista zawiera zagnieżdżone, modyfikowalne obiekty (takie jak listy lub słowniki), płytka kopia zduplikuje jedynie zewnętrzny kontener; zagnieżdżone obiekty pozostają wspólne. Modyfikowanie listy zagnieżdżonej w kopii spowoduje zmianę oryginalnej listy. Aby temu zapobiec, musisz wykonać głęboką kopię za pomocą funkcji `deepcopy()` modułu `copy`, która rekurencyjnie klonuje każdy obiekt w hierarchii.

Dane wyjściowe kodu i wykonania

Ten kod demonstruje pułapkę przypisania odwołań, płytkie kopiowanie przy użyciu list.copy() i głębokie kopiowanie list zagnieżdżonych przy użyciu modułu kopiowania.

copy_lists.py
Spróbuj w Edytorze
import copy

# 1. The assignment reference trap (Not a copy!)
original = [1, 2, 3]
reference = original
reference.append(99)
print("Reference modification affects original:", original)

# Reset list
original = [1, 2, 3]

# 2. Creating a shallow copy (using list.copy())
shallow_copy = original.copy()
shallow_copy.append(100)
print("\nOriginal:", original)
print("Shallow copy:", shallow_copy)

# 3. The nested list limitation of shallow copies
nested = [[1, 2], [3, 4]]
shallow_nested = nested.copy()
shallow_nested[0].append(99) # Modifying nested list
print("\nOriginal nested:", nested)
print("Shallow nested copy:", shallow_nested)

# 4. Creating a deep copy
nested_original = [[1, 2], [3, 4]]
deep_copy = copy.deepcopy(nested_original)
deep_copy[0].append(99)
print("\nOriginal nested:", nested_original)
print("Deep copy (completely independent):", deep_copy)
Wyjście terminala
Reference modification affects original: [1, 2, 3, 99]

Original: [1, 2, 3]
Shallow copy: [1, 2, 3, 100]

Original nested: [[1, 2, 99], [3, 4]]
Shallow nested copy: [[1, 2, 99], [3, 4]]

Original nested: [[1, 2], [3, 4]]
Deep copy (completely independent): [[1, 2, 99], [3, 4]]

Wdrażanie krok po kroku

  • Użyj my_list.copy() lub my_list[:], aby utworzyć płytką kopię struktur list płaskich.
  • Unikaj przypisań referencyjnych, takich jak copy_list = my_list, gdy potrzebujesz niezależnych kolekcji.
  • Zaimportuj moduł kopiowania i użyj funkcji copy.deepcopy(my_list) w przypadku list zawierających zagnieżdżone, modyfikowalne struktury.
  • Upewnij się, że rozumiesz struktury danych, aby zoptymalizować wydajność i wykorzystanie pamięci.

Często zadawane pytania

Jaka jest różnica między płytką kopią a głęboką kopią?

Płytka kopia kopiuje najbardziej zewnętrzny kontener, ale odwołuje się do zagnieżdżonych obiektów zmiennych. Głęboka kopia rekurencyjnie duplikuje wszystkie zagnieżdżone kontenery i obiekty, co skutkuje całkowicie izolowanymi strukturami danych.

Czy dzielenie listy (list[:]) jest szybsze niż list.copy()?

Są praktycznie identyczne pod względem wydajności, ponieważ oba wykonują zoptymalizowane operacje C pod maską. Ze względu na czytelność ogólnie preferowane jest używanie list.copy().

Powiązane tematy

Polecane zasoby Pythona

Poszerzaj swoją wiedzę dzięki powiązanym interaktywnym samouczkom, ściągawkom i porównaniom kodów.