2016-03-10 17 views
5

mam pytanie o metody słownika kopiowania na przykład powiedzmy mamPython słownik kopia metoda

>> d = {'pears': 200, 'apples': 400, 'oranges': 500, 'bananas': 300} 

>> copy_dict = d.copy() 

Teraz gdybym sprawdzić identyfikatory obu d i copy_dict, oba są różne

>> id(d) 
o/p = 140634603873176 

>> id(copy_dict) 
o/p = 140634603821328 

ale jeśli sprawdzam id obiektów w słownikach, mają one takie samo znaczenie id (d ['gruszki']) = id (copy_dict ['pears'])

>> id(d['pears']) 
o/p = 140634603971648 
>> id (copy_dict['pears']) 
o/p = 140634603971648 

Wszystkie obiekty w nowym dykcie są odniesieniami do tych samych obiektów, co oryginalny dict.

Teraz, jeśli zmienię wartość klucza 'gruszki' w d, nie ma zmiany w tym samym kluczu w copy_dict i kiedy sprawdzam id's teraz, id (d ['gruszki'])! = Id (copy_dict [ „gruszki”])

>> d['pears'] = 700 
>> print copy_dict['pears'] 
o/p = 200 

Moje pytanie brzmi, czy obiekty w nowych dict są odniesienia do tych samych obiektów jak oryginalnego dict dlaczego jest wartość nowej dict nie uległ zmianie, gdy wartość w oryginale słownik zmienił się i jak Python natychmiast zmienił identyfikator, gdy tylko zobaczył zmianę wartości?

Czy możesz podać mi pełny opis różnicy między głęboką i płytką kopią?

+0

Możliwy duplikat [Understanding dict.copy() - shallow or deep?] (Http://stackoverflow.com/questions/3975376/understanding-dict-copy-shallow-or-deep) – Backtrack

Odpowiedz

2

Zmieniając wartość, zmieniasz wskazanie klawisza. Zmiana wartości w oryginalnym słowniku nie zmieni tego, na co wskazuje klucz w kopii.

Płytka kopii tworzy nowy obiekt związku a potem (do miarę możliwości) jest wprowadzany do niego odniesienie do przedmiotów znajdujących się w oryginału.

Głęboka kopia tworzy nowy obiekt złożony, a następnie rekurencyjnie wstawia do niego kopie obiektów znalezionych w oryginale .

Podczas kopiowania coś kopiuje oryginalne wartości kopiowanego obiektu, ale tworzy nowy obiekt. Nie odzwierciedla oryginalnego obiektu.

+0

Ale kiedy kopiujemy coś obiekty w nowym dykcie są odniesieniami do tych samych obiektów, co pierwotne znaczenie dict, oba adresy są takie same, co jest aliasingiem, więc zmiany wprowadzone do jednego powinny również zmienić nowe prawo dict? ponieważ oba wskazują na ten sam adres. – sans0909

+0

Nie, używając funkcji copy(), tworzysz nowy obiekt. Użyłbyś operatora przypisania do tego, co próbujesz zrobić: 'copy_dict = d', a kiedy zaktualizujesz' d', to również zaktualizuje 'copy_dict', ponieważ są one tym samym obiektem. – lciamp

+0

dziękuję @lciamp – sans0909

0

Powodem jest to, że wykonano operację przypisania, która zastępuje wartości, a nie operację modyfikacji wartości.

copy_dict = d.copy() 

spowodował nowy dict być tworzone i jej klucze/wartości zostały zainicjowany z d. Zauważyłeś ważny punkt - są to oddzielne obiekty z różnymi identyfikatorami, które po prostu odnoszą się do tych samych kluczy i wartości.

d['pears'] = 700 

usunięto odniesienie do 200 z d['pears'] i dodano odniesienie do 700. To przeniesienie zostało wykonane na samym obiekcie d, więc naturalnie nie byłoby widziane przez inne dyktety, które zostały po prostu zainicjowane przez te same klucze i wartości.

W przeciwieństwie do rzekomego trzeba było po prostu przypisany oryginalny dict do drugiej zmiennej

copy_dict = d 

Tutaj, ponieważ zarówno d i copy_dict odniesienia samo dict, przeniesieniu na tym dict byłaby postrzegana przez obu zmiennych, ponieważ odnoszą się do tego samego obiektu.

+0

Dziękuję bardzo, teraz jest jasne :-) – sans0909