W tym przykładzie x is zzwraca False. Ale jeśli x i z mają przypisane te same wartości zamiast list (na przykład x, z = 13, 13), to x is zzwraca True. Dlaczego?
Bill
12
@Bill: To jest artefakt tego, jak Python obsługuje wartości int. Python przydziela obiekty będące liczbami całkowitymi, do których xi które zwskazują. Ponieważ małe liczby całkowite są typowe dla awarii (-1 jako wartość błędu, 0 za każdym razem, gdy coś faktycznie indeksujesz, małe liczby są zwykle rozsądnymi wartościami domyślnymi) .Python optymalizuje, wstępnie przydzielając małe liczby (od -5 do 256) i ponownie wykorzystuje ten sam obiekt typu integer. Zatem twój przykład działa tylko dla liczb z tego zakresu. Spróbuj przypisać coś większego, np 270. Aby uzyskać więcej informacji, zajrzyj tutaj
ted
1
@AndresR Nie, to źle. issprawdza, czy dwie nazwy odnoszą się do tej samej lokalizacji pamięci. Nie ma to nic wspólnego z samym przedmiotem. Łatwo jest mieć niezmienne obiekty, takie jak ciągi znaków, które są równe, ale nie są przechowywane w tym samym miejscu, na przykład ''a'*10000 is 'a' * 10000ma wartość False.
Jochen Ritzel
1
@JochenRitzel Masz całkowitą rację, dziękuję za ten komentarz! Więc nie rozumiem, co się dzieje "af" is "af"lub () is ()... dlaczego mają to samo miejsce w pamięci?
AndresR,
2
@AndreasR W przypadku literału ciągów / liczb w kodzie kompilator sprawdza, czy istnieją one tylko raz i ponownie je wykorzystuje. Specjalne wartości, takie jak (), None, True, False itp. Są również zdefiniowane jako pojedyncze. Podczas wykonywania środowisko wykonawcze również próbuje ponownie użyć małych liczb i ciągów, ale ostatecznie jest to kompromis między szybkością a pamięcią, a to, co się stanie, zależy od tego, jak zaimplementowano środowisko wykonawcze Pythona.
Uwaga @ teda na temat używania identyfikatora jest tutaj dość istotna.
Leo Ufimtsev
11
Podczas gdy dwa poprawne rozwiązania x is zi id(x) == id(z)zostały już wysłane, chcę podkreślić szczegółów wdrażania Pythona. Python przechowuje liczby całkowite jako obiekty, w ramach optymalizacji generuje na początku kilka małych liczb całkowitych (od -5 do 256) i wskazuje KAŻDĄ zmienną zawierającą liczbę całkowitą o małej wartości na te wstępnie zainicjowane obiekty. Więcej informacji
Oznacza to, że dla obiektów typu integer zainicjowanych na te same małe liczby (od -5 do 256) sprawdzenie, czy dwa obiekty są takie same, zwróci wartość true ( ON C-Pyhon , o ile wiem, jest to szczegół implementacji ), podczas gdy dla większych liczby zwraca to prawdę tylko wtedy, gdy jeden obiekt jest inicjowany z drugiego.
> i = 13
> j = 13
> i is j
True
> a = 280
> b = 280
> a is b
False
> a = b
> a
280
> a is b
True
To pochodzi z docs.python.org: „Każdy obiekt ma tożsamość, typ i wartość. Tożsamość obiektu nigdy się nie zmienia po jego utworzeniu; możesz myśleć o tym jako o adresie obiektu w pamięci. Operator„ is ” porównuje tożsamość dwóch obiektów; funkcja id () zwraca liczbę całkowitą reprezentującą jego tożsamość. "
Najwyraźniej za każdym razem, gdy zmieniasz wartość, obiekt jest odtwarzany, na co wskazuje zmiana tożsamości. Linia x = 3, po której następuje linia x = 3,14, nie daje błędu i podaje różne tożsamości, typy i wartości x.
xJest to nazwa identyfikacji obiektu z wartości z 3, a nie obiektu sama. Kiedy to zrobiłeś x=3.14, nie zmieniłeś obiektu, który był wcześniej identyfikowany x- zmieniłeś obiekt, do którego odnosiła się nazwax .
Odpowiedzi:
To
is
jest dla:x is y
zwraca,True
jeślix
iy
są tym samym obiektem.źródło
x is z
zwracaFalse
. Ale jeśli x i z mają przypisane te same wartości zamiast list (na przykładx, z = 13, 13
), tox is z
zwracaTrue
. Dlaczego?x
i którez
wskazują. Ponieważ małe liczby całkowite są typowe dla awarii (-1 jako wartość błędu, 0 za każdym razem, gdy coś faktycznie indeksujesz, małe liczby są zwykle rozsądnymi wartościami domyślnymi) .Python optymalizuje, wstępnie przydzielając małe liczby (od -5 do 256) i ponownie wykorzystuje ten sam obiekt typu integer. Zatem twój przykład działa tylko dla liczb z tego zakresu. Spróbuj przypisać coś większego, np270
. Aby uzyskać więcej informacji, zajrzyj tutajis
sprawdza, czy dwie nazwy odnoszą się do tej samej lokalizacji pamięci. Nie ma to nic wspólnego z samym przedmiotem. Łatwo jest mieć niezmienne obiekty, takie jak ciągi znaków, które są równe, ale nie są przechowywane w tym samym miejscu, na przykład''a'*10000 is 'a' * 10000
ma wartość False."af" is "af"
lub() is ()
... dlaczego mają to samo miejsce w pamięci?y is x
będzieTrue
,y is z
będzieFalse
.źródło
Możesz także użyć id (), aby sprawdzić, do którego unikalnego obiektu odnosi się każda nazwa zmiennej.
In [1]: x1, x2 = 'foo', 'foo' In [2]: x1 == x2 Out[2]: True In [3]: id(x1), id(x2) Out[3]: (4509849040, 4509849040) In [4]: x2 = 'foobar'[0:3] In [5]: x2 Out[5]: 'foo' In [6]: x1 == x2 Out[6]: True In [7]: x1 is x2 Out[7]: False In [8]: id(x1), id(x2) Out[8]: (4509849040, 4526514944)
źródło
Podczas gdy dwa poprawne rozwiązania
x is z
iid(x) == id(z)
zostały już wysłane, chcę podkreślić szczegółów wdrażania Pythona. Python przechowuje liczby całkowite jako obiekty, w ramach optymalizacji generuje na początku kilka małych liczb całkowitych (od -5 do 256) i wskazuje KAŻDĄ zmienną zawierającą liczbę całkowitą o małej wartości na te wstępnie zainicjowane obiekty. Więcej informacjiOznacza to, że dla obiektów typu integer zainicjowanych na te same małe liczby (od -5 do 256) sprawdzenie, czy dwa obiekty są takie same, zwróci wartość true ( ON C-Pyhon , o ile wiem, jest to szczegół implementacji ), podczas gdy dla większych liczby zwraca to prawdę tylko wtedy, gdy jeden obiekt jest inicjowany z drugiego.
> i = 13 > j = 13 > i is j True > a = 280 > b = 280 > a is b False > a = b > a 280 > a is b True
źródło
Bardzo lubię wizualną informację zwrotną, dlatego czasami po prostu otwieram http://www.pythontutor.com/visualize.html#mode=edit, aby zobaczyć, jak przydzielana jest pamięć i do czego się odwołuje.
Dodano ten niesamowity gif, ponieważ ta odpowiedź dotyczy wizualizacji ...
źródło
To pochodzi z docs.python.org: „Każdy obiekt ma tożsamość, typ i wartość. Tożsamość obiektu nigdy się nie zmienia po jego utworzeniu; możesz myśleć o tym jako o adresie obiektu w pamięci. Operator„ is ” porównuje tożsamość dwóch obiektów; funkcja id () zwraca liczbę całkowitą reprezentującą jego tożsamość. "
Najwyraźniej za każdym razem, gdy zmieniasz wartość, obiekt jest odtwarzany, na co wskazuje zmiana tożsamości. Linia x = 3, po której następuje linia x = 3,14, nie daje błędu i podaje różne tożsamości, typy i wartości x.
źródło
x
Jest to nazwa identyfikacji obiektu z wartości z3
, a nie obiektu sama. Kiedy to zrobiłeśx=3.14
, nie zmieniłeś obiektu, który był wcześniej identyfikowanyx
- zmieniłeś obiekt, do którego odnosiła się nazwax
.