, 5 min czytaniaprogramowaniereferencje
Dlaczego „b = a” nie kopiuje listy
Jeden znak równości, dwie nazwy i cicho zepsute zadanie. Skąd się bierze aliasing i jak go nie wpuścić do swojego kodu.
Zmienna w Pythonie nie jest pudełkiem, w którym leży lista. Jest wizytówką ze wskazaniem, gdzie ta lista się znajduje. Przypisanie kopiuje wizytówkę, a nie to, co ona wskazuje.
1a = [1, 2, 3]2b = a3b.append(4)4print(a) # [1, 2, 3, 4]
Lista a ma cztery elementy, mimo że nikt jej nie dotykał. Bo „jej” lista to ta sama lista, którą zmieniało b. W pamięci cały czas istniał tylko jeden obiekt.
Dlaczego przy liczbach ten problem nie występuje
Liczby i napisy są niezmienne: nie da się zmienić samej piątki. Zapis y = y + 1 nie modyfikuje starej wartości, tylko tworzy nową i przestawia na nią wizytówkę. Lista jest inna: append zmienia ten sam obiekt, który widzą wszystkie wskazujące na niego nazwy.
Jak zrobić prawdziwą kopię
1b = a[:] # wycinek tworzy nową listę2b = list(a) # to samo, inaczej zapisane
Gdzie to boli na egzaminie
- Przekazujesz listę do funkcji, funkcja ją sortuje i tracisz oryginalną kolejność potrzebną w następnym podpunkcie.
- Robisz kopię „na wszelki wypadek” przez przypisanie i po godzinie nie wiesz, dlaczego oba zbiory mają te same zmiany.
- Tworzysz tablicę dwuwymiarową przez [[0] * 3] * 3, a zmiana jednej komórki zmienia całą kolumnę, bo wiersze to ten sam obiekt powtórzony trzy razy.
Najszybszy sposób, żeby to zobaczyć zamiast zapamiętać: uruchomić oba warianty obok siebie i policzyć, ile obiektów naprawdę powstało w pamięci.