python list.copy shallow vs deep copy [duplicat] (Programare, Python, Lista, Copie Profundă, Copie Superficială)

RSHAP a intrebat.

Poate că nu înțeleg definiția copiei superficiale… dar sunt foarte confuz:

din documentație:

În cazul în care „s” este o listă (dar aceeași întrebare se aplică și la dicționare, respectiv).

„s.copy() | creează o copie superficială a lui s (la fel ca s[:])”

Doar că eu credeam că s[:] era o copie profundă. De exemplu, consultați acest răspuns de la stack overflow despre cum să copiați o listă (fără ca aceasta să arate doar spre versiunea originală). Și utilizarea list1.copy() pare să facă o copie profundă, de asemenea, aka același comportament ca și [:]

l1 = [1,2,3,4]
l2 = l1[:]
l3 = l1.copy()



l2.append(5)
l3[0] = 99
print(l1)
print(l2)
print(l3)
>> [1,2,3,4]
>> [1,2,3,4,5]
>> [99,2,3,4]

S-ar părea că l1,l2, și l3 sunt toate separate obiecte separate. Ce îmi scapă?

Comentarii

  • … dacă schimb l1 cu o listă de liste de numere, tot obțin același lucru – l1.copy() pare să creeze un obiect separat…  > Por RSHAP.
  • Nu, ambele sunt copii superficiale. Distincția în această întrebare este între o simplă atribuire (care nu copiază deloc) și o copie (una superficială) –  > Por juanpa.arrivillaga.
  • @juanpa.arrivillaga, Ahhhh ok, văd că asta răspunde la întrebare. –  > Por RSHAP.
  • @RSHAP puteți testa egalitatea profundă cu is și pentru egalitatea superficială cu ==. Aici egalitatea profundă implică egalitatea superficială. (l1 is l2 este True numai dacă ambele referințe indică același obiect, în timp ce l1 == l2 este True atunci când toate valorile lui l1 și l2 sunt egale) – –  > Por Chris.
2 răspunsuri
Daniel Roseman

Pur și simplu ați înțeles greșit ce înseamnă „superficial” și „profund” în acest context.

O copie superficială este o copie doar a nivelului superior de elemente. Dacă oricare dintre aceste elemente sunt ele însele liste, copiile se vor referi în continuare la listele originale. Aceasta este ceea ce înseamnă atât l1[:] și l1.copy() fac.

O copie profundă este o copie la toate nivelurile. Dacă oricare dintre elemente sunt liste, acestea vor fi, de asemenea, copiate în profunzime. Nu vor fi partajate referințe. Aceasta este ceea ce copy.deepcopy() face.

mgilson

O copiere superficială înseamnă că noua listă deține referințe la același obiect pe care îl are și vechea listă.

De exemplu:

foo = [1, 2, []]
bar = foo.copy()
bar[-1].append(3)
print(foo)

Vom vedea că mutațiile de obiecte din bar de asemenea, „poluează” foo.

Dacă refacem acest exemplu folosind o copie profundă, este o altă poveste:

import copy
foo = [1, 2, []]
bar = copy.deepcopy(foo)
bar[-1].append(3)
print(foo)

Acest lucru se datorează faptului că copia în profunzime creează o nouă (copie în profunzime) a listei în loc să copieze doar o referință la vechea listă.