Podczas czytania dokumentacji dict.copy()
napisano, że tworzy ona płytką kopię słownika. To samo dotyczy książki, którą obserwuję (Beazley's Python Reference), która mówi:
Metoda m.copy () tworzy płytką kopię elementów zawartych w obiekcie odwzorowującym i umieszcza je w nowym obiekcie odwzorowującym.
Rozważ to:
>>> original = dict(a=1, b=2)
>>> new = original.copy()
>>> new.update({'c': 3})
>>> original
{'a': 1, 'b': 2}
>>> new
{'a': 1, 'c': 3, 'b': 2}
Więc założyłem, że to zaktualizuje wartość original
(i doda „c”: 3) również, ponieważ robiłem płytką kopię. Na przykład, jeśli robisz to dla listy:
>>> original = [1, 2, 3]
>>> new = original
>>> new.append(4)
>>> new, original
([1, 2, 3, 4], [1, 2, 3, 4])
Działa to zgodnie z oczekiwaniami.
Skoro oba są płytkimi kopiami, dlaczego dict.copy()
nie działa tak, jak się spodziewam? Czy moje rozumienie kopiowania płytkiego vs. głębokiego jest błędne?
python
dictionary
copy
użytkownik225312
źródło
źródło
Odpowiedzi:
Przez „płytkie kopiowanie” oznacza to, że zawartość słownika nie jest kopiowana według wartości, a jedynie tworzenie nowego odwołania.
Natomiast głęboka kopia skopiuje całą zawartość według wartości.
Więc:
b = a
: Przypisanie odniesienia, markaa
ib
wskazuje ten sam obiekt.b = a.copy()
: Płytkie kopiowaniea
ib
staną się dwoma odizolowanymi obiektami, ale ich zawartość nadal będzie mieć to samo odwołanieb = copy.deepcopy(a)
: Głębokie kopiowanie,a
ab
struktura i treść zostają całkowicie odizolowane.źródło
L
ponownieb
. Takie postępowanie uprościłoby przykład.b[1][0] = 5
. Jeślib
jest to płytka kopia, właśnie się zmieniłeśa[1][0]
.Nie jest to kwestia głębokiej lub płytkiej kopii, żadne z tych działań nie jest głęboką kopią.
Tutaj:
tworzysz nowe odwołanie do listy / słownika, do którego odwołuje się oryginał.
podczas gdy tutaj:
tworzysz nową listę / dict, która jest wypełniona kopią referencji obiektów zawartych w oryginalnym pojemniku.
źródło
Weź ten przykład:
Teraz zmieńmy wartość na „płytkim” (pierwszym) poziomie:
Teraz zmieńmy wartość o jeden poziom głębiej:
źródło
no change in original, since ['a'] is an immutable integer
To. W rzeczywistości odpowiada na zadane pytanie.Dodanie do odpowiedzi KennyTM. Gdy wykonujesz płytką kopię parent.copy (), tworzony jest nowy słownik z tymi samymi kluczami, ale wartości nie są kopiowane, do których się odwołują. Jeśli dodasz nową wartość do parent_copy , nie wpłynie to na parent, ponieważ copy_copy jest nowym słownikiem brak odniesienia.
Hash (ID) wartości macierzystego [1] , parent_copy [1], są takie same co oznacza, [1,2,3], o dominującej [1] i parent_copy [1] przechowywano w identyfikatorze 140690938288400.
Ale skróty typu parent i parent_copy są różne, co oznacza, że są to różne słowniki, a parent_copy to nowy słownik o wartościach odniesienia do wartości typu parent
źródło
„nowe” i „oryginalny” są różne dicts, dlatego można aktualizować tylko jeden z nich .. Te przedmioty są płytkie, kopiowane, a nie sam dict.
źródło
Treści są płytko kopiowane.
Więc jeśli oryginał
dict
zawiera jedenlist
lub innydictionary
, modyfikowanie jednego z nich w oryginale lub jego płytkiej kopii spowoduje modyfikację ich (tegolist
lubdict
drugiego) w drugim.źródło
W drugiej części powinieneś użyć
new = original.copy()
.copy
i=
są różne rzeczy.źródło