Chciałbym zrobić głęboką kopię dict
Pythona. Niestety .deepcopy()
metoda nie istnieje dla dict
. Jak mogę to zrobić?
>>> my_dict = {'a': [1, 2, 3], 'b': [4, 5, 6]}
>>> my_copy = my_dict.deepcopy()
Traceback (most recent calll last):
File "<stdin>", line 1, in <module>
AttributeError: 'dict' object has no attribute 'deepcopy'
>>> my_copy = my_dict.copy()
>>> my_dict['a'][2] = 7
>>> my_copy['a'][2]
7
Ostatnia linia powinna być 3
.
Chciałbym, aby te modyfikacje my_dict
nie miały wpływu na migawkę my_copy
.
Jak mogę to zrobić? Rozwiązanie powinno być kompatybilne z Python 3.x.
python
python-3.x
Olivier Grégoire
źródło
źródło
Odpowiedzi:
Co powiesz na:
Python 2 lub 3:
źródło
copy.deepcopy
nie jest bezpieczny dla wątków. Nauczyłem się tego na własnej skórze. Z drugiej strony, w zależności od przypadku użycia,json.loads(json.dumps(d))
jest bezpieczny dla wątków i działa dobrze.json.loads
że nie rozwiązuje on problemu we wszystkich przypadkach użycia, w którychdict
atrybuty Pythona nie są serializowane przez JSON. Może to pomóc tym, którzy mają do czynienia tylko z prostymi strukturami danych, na przykład z API, ale nie sądzę, że to wystarczające rozwiązanie, aby w pełni odpowiedzieć na pytanie OP.dict.copy () to płytka funkcja kopiowania dla słownika
id jest wbudowaną funkcją, która podaje adres zmiennej
Najpierw musisz zrozumieć „dlaczego tak się dzieje?”
Adres listy występującej w obu nagraniach dla klucza „a” wskazuje tę samą lokalizację.
Dlatego po zmianie wartości listy w my_dict zmienia się również lista w my_copy.
Rozwiązanie dla struktury danych wspomniane w pytaniu:
Lub możesz użyć deepcopy, jak wspomniano powyżej.
źródło
value[:]
. Rozwiązaniem była konkretna struktura danych wspomniana w pytaniu, a nie rozwiązanie uniwersalne.Python 3.x
z kopiowania importu kopii
Bez szczegółowej analizy nie mogę usunąć słownika nazw hostów ze słownika domen.
Bez głębokiej kopii pojawia się następujący błąd:
... kiedy próbuję usunąć pożądany element z mojego słownika w innym słowniku.
domena jest obiektem słownika
Przykładowe dane wyjściowe: [orginal] domains = {'localdomain': {'localhost': {'all': '4000'}}}
[new] domains = {'localdomain': {}}}
To, co się tutaj dzieje, to iteracja nad kopią słownika, a nie iteracja nad samym słownikiem. Dzięki tej metodzie możesz usuwać elementy w razie potrzeby.
źródło
Bardzo lubię i dużo się nauczyłem od Lasse V. Karlsen. Zmodyfikowałem go w następujący przykład, który dość dobrze podkreśla różnicę między płytkimi kopiami słownika a kopiami głębokimi:
Teraz jeśli się zmienisz
i robić
dostajesz
źródło
Prostszym (moim zdaniem) rozwiązaniem jest utworzenie nowego słownika i zaktualizowanie go o zawartość starego:
Problem z tym podejściem polega na tym, że może nie być on „wystarczająco głęboki”. tzn. nie jest rekurencyjnie głęboki. wystarczająco dobre dla prostych obiektów, ale nie dla zagnieżdżonych słowników. Oto przykład, w którym może nie być wystarczająco głęboki:
Korzystając z Deepcopy (), mogę wyeliminować częściowo płytkie zachowanie, ale myślę, że należy zdecydować, które podejście jest odpowiednie dla twojej aplikacji. W większości przypadków możesz się tym nie przejmować, ale powinieneś zdawać sobie sprawę z możliwych pułapek ... ostatni przykład:
źródło
my_dict.copy()
!