2010-11-11 35 views
5

Czy ktoś może mi to wyjaśnić?tuple vs list obiektów w python

>>> [] is [] 
False 
>>>() is() 
True 
>>> (1,) is (1,) 
False 

Rozumiem, że powinno się używać „==” zamiast „jest”, aby porównać wartości, jestem po prostu zastanawiasz się, dlaczego jest to w ten sposób?

Odpowiedz

10

is opiera się na tożsamości obiektu. I.E., czy lewy i prawy to ten sam obiekt?

We wszystkich tych przypadkach obiekty byłyby zwykle inne (ponieważ masz sześć oddzielnych literałów). Jednak puste krotki są tym samym obiektem ze względu na zależne od implementacji interning. Jak zauważyłeś, nigdy nie powinieneś polegać na tym zachowaniu.

Należy zauważyć, że zmienne obiekty nie mogą być internowane, co oznacza, że ​​pierwszy musi być fałszywy.

+2

Uwaga "internowania" może (zwykle ma) stosuje się do strun, a także każdej innej niezmiennej dosłownym/wartość. Ponieważ są one niezmienne, każda implementacja Pythona ma opcję tworzenia różnych odniesień zbiegających się (wskazywać) na dowolne pojedyncze wystąpienie obiektu. To właśnie oznacza interning w tym kontekście. Interning to szczegół implementacji, który optymalizuje się pod kątem typowych przypadków użycia. Listy Pythona są zresztą zmienne i nie mogą być przedmiotem interwencji. –

+1

Pierwsza nie jest porównaniem listy i krotki, ale między dwiema listami. Jest to wartość false, ponieważ są to różne obiekty (to znaczy różne identyfikatory), które mają tylko tę samą wartość (tj. Obie są pustymi listami). – rbp

+0

@rbp, dzięki, źle odczytałem pytanie. –

2

Pomyśl o tym w ten sposób: W pierwszym przypadku, dla niezmiennych obiektów takich jak krotek, to bezpieczne dla implementacja Pythona, aby dzielić się nimi, jeśli są identyczne:

>>> a =() 
>>> b =() 
>>> a is b 
True 

Rozważmy teraz:

>>> a = [] 
>>> b = [] 
>>> a.append("foo") 
>>> print a,b 
['foo'] [] 

Nie jest możliwe, aby aib były tym samym obiektem, ponieważ modyfikacja nie powinna modyfikować b.

W swoim ostatnim przykładzie powróciłeś do niezmiennych krotek. Wdrożenie w języku Python to , które zezwala na, aby uczynić je tym samym obiektem, ale nie jest do tego wymagane, a w tym przypadku nie (to w zasadzie kompromis czasoprzestrzenny - jeśli używałeś dużo (1,) w swoim program mógłbyś zaoszczędzić pamięć, gdyby był internowany, ale kosztowałoby to środowisko wykonawcze, aby określić, czy dana krotka była (1,), która mogłaby współdzielić obiekt).

3

Należy zachować ostrożność podczas porównywania według identyfikatora. Jeśli obiekt jest GC, identyfikator może być ponownie użyty!

>>> id([])==id([]) 
True 

lub nawet

>>> id([1,2,3])==id(["A","B","C"]) 
True 
+0

Doskonały punkt! – rbp