python: Dołączanie słownika do listy - widzę wskaźnik podobny do zachowania

85

Wypróbowałem następujące w interpreterze Pythona:

>>>
>>> a = []
>>> b = {1:'one'}
>>> a.append(b)
>>> a
[{1: 'one'}]
>>> b[1] = 'ONE'
>>> a
[{1: 'ONE'}]
>>>

Tutaj po dołączeniu słownika „b” do listy „a” zmieniam wartość odpowiadającą kluczowi 1 w słowniku „a”. W jakiś sposób ta zmiana zostaje również odzwierciedlona na liście. Czy dołączając słownik do listy, nie dołączam tylko wartości słownika? Wygląda na to, że dołączyłem wskaźnik do słownika do listy, a zatem zmiany w słowniku są również odzwierciedlane na liście.

Nie chcę, aby zmiana została odzwierciedlona na liście. Jak mam to zrobić?

Dziękuję za Twój czas!

neo29
źródło
Czechow To nie jest słownik „b” , jest to słownik b lub słownik o nazwie „b” . Nawiasem mówiąc, omyłkowo napisałeś: „Zmieniam wartość odpowiadającą kluczowi 1 w słowniku 'a'” Nie, w słowniku b. A propos twojego zdziwienia: lista nie zawiera wartości, zawiera obiekty, ponieważ w Pythonie wszystko jest obiektami. A dokładniej lista zawiera odniesienia do obiektów.
eyquem,
Czechow Powinieneś także zobaczyć to pytanie: ( stackoverflow.com/questions/5242933/… )
eyquem
@eyquem dzięki za komentarz. Publikowałem to w pośpiechu. Przepraszam.
neo29
Czechow To nie był zarzut, to była tylko informacja. Nawiasem mówiąc, jeśli moja odpowiedź jest nieco przydatna, można ją przegłosować. Możesz także „zaakceptować” jedną odpowiedź spośród odpowiedzi, klikając na pasek w kształcie szewronu pod licznikiem punktów po lewej stronie jednej odpowiedzi, otrzymasz 25 punktów. Możesz też nie akceptować żadnego pytania.
eyquem

Odpowiedzi:

140

Masz rację, ponieważ lista zawiera odniesienie do oryginalnego słownika.

a.append(b.copy()) powinien załatwić sprawę.

Pamiętaj, że tworzy to płytką kopię. Alternatywą jest użycie copy.deepcopy(b), które tworzy głęboką kopię.

NPE
źródło
6
niesamowite! Byłem przez długi czas zablokowany
Yasin
2
to mnie zaskakiwało przez około pół godziny, aż poddałem się i zdecydowałem sprawdzić stack.
FlyingZebra1
35

Również z dyktando

a = []
b = {1:'one'}

a.append(dict(b))
print a
b[1]='iuqsdgf'
print a

wynik

[{1: 'one'}]
[{1: 'one'}]
eyquem
źródło
Nie jestem pewien, czy jest wystarczająco szybki jak copy (), ale wydaje się być szybszy niż deepcopy (). Może ze skomplikowanym schematem słownikowym będzie blisko funkcji deepcopy (), ponieważ dict () tworzy nowy słownik.
selotec