Czy istnieje różnica między „= =” a „jest”?
Mój
Google-fu
https://english.stackexchange. ... -mean
nie dla mnie.
Czy w Pythonie poniższe dwa testy równości są równoważne?
n = 5
# Test one.
if n == 5:
print 'Yay!'# Test two.
if n is 5:
print 'Yay!'
Czy jest to prawdą w przypadku obiektów, w których można porównać wystąpienia (np.
lista)?
Oto odpowiedź na moje pytanie:
L = []
L.append(1)
if L == [1]:
print 'Yay!'
# Holds true, but...if L is [1]:
print 'Yay!'
# Doesn't.
Czyli wartość
==tests, gdzie
totesty, aby sprawdzić, czy są to ten sam obiekt?
Nie znaleziono powiązanych wyników
Zaproszony:
Aby odpowiedzieć na pytania, Zaloguj się lub Zarejestruj się
14 odpowiedzi
Anonimowy użytkownik
Potwierdzenie od:
W twoim przypadku drugi test działa tylko dlatego, że Python buforuje małe obiekty całkowite, co jest szczegółem implementacji. W przypadku dużych liczb całkowitych to nie działa:
To samo dotyczy literałów ciągów:
Przeczytaj również
to pytanie
https://coderoad.ru/26595/
.
Anonimowy użytkownik
Potwierdzenie od:
Ogólnie rzecz biorąc, kiedy porównujesz coś do prostego typu, zwykle sprawdzasz
równość wartości
więc powinieneś użyć . Na przykład celem twojego przykładu jest prawdopodobnie sprawdzenie, czy x ma wartość 2 ( ), a nie to, że odnosi się dosłownie do tego samego obiektu co 2.
Jeszcze jedna uwaga, ze względu na sposób działania implementacji referencyjnej CPythona, otrzymasz nieoczekiwane i sprzeczne wyniki, jeśli omyłkowo użyjesz do porównania równości referencji z liczbami całkowitymi:
Dokładnie tego się spodziewaliśmy: i mają to samo znaczenie, ale są różnymi jednostkami. Ale co z tym?
Jest to niezgodne z poprzednim wynikiem. Co tu się dzieje? Okazuje się, że implementacja Pythona, do której się odwołujemy, buforuje obiekty całkowite z zakresu -5..256 jako pojedyncze instancje ze względu na wydajność. Oto przykład, aby to zademonstrować:
Jest to kolejny oczywisty powód, aby nie używać : zachowanie pozostaje do zaimplementowania, gdy omyłkowo użyjesz go do równości wartości.
Anonimowy użytkownik
Potwierdzenie od:
Czy jest różnica między a w Pythonie?
>Tak, mają bardzo ważną różnicę.
: test równości - semantyka polega na tym, że równoważne obiekty (które niekoniecznie są tym samym obiektem) będą testowane jako równe. w jaki sposób
tak jest napisane w dokumentacji
https://docs.python.org/3/refe ... isons
:
Operatory & <, & >, ==, & > =, & < = i nie tylko! = Porównaj wartości dwóch obiektów.
: semantyka sprawdzania tożsamości polega na tym, że obiekt (przechowywany w pamięci)
jest
obiekt. Ponownie w
dokumentacja mówi
https://docs.python.org/3/refe ... s-not
: :
Instrukcje i sprawdzają tożsamość obiektu: is true
wtedy i tylko wtedy, gdy i to ten sam obiekt. Tożsamość obiektu to
jest zdefiniowana za pomocą funkcji . daje odwrotny wynik
wartość prawdy.
Dlatego sprawdzanie tożsamości jest tym samym, co sprawdzanie równości identyfikatorów obiektów. To znaczy,
to jest to samo co:
gdzie to wbudowana funkcja zwracająca liczbę całkowitą, która „gwarantuje unikalność wśród jednocześnie istniejących obiektów” (patrz ) i gdzie i to dowolne obiekty.
Inne zastosowania
>
Powinieneś użyć tych porównań dla ich semantyki. Użyj , aby sprawdzić tożsamość, i , aby sprawdzić równość.
PEP 8, oficjalny przewodnik po stylu Pythona dla standardowej biblioteki również wspomina
dwa przypadki użycia dlahttps://www.python.org/dev/pep ... tions
:
Porównania singletowe typu powinny być zawsze dokonywane za pomocą lub , nigdy operatorów równości.
Uważaj również na pisanie , kiedy naprawdę masz na myśli -
na przykład podczas sprawdzania, czy zmienna lub argument o wartości domyślnej został ustawiony na inną wartość. Inna wartość może być typu (na przykład
jako kontener), co może być fałszywe w kontekście logicznym!
Definicje równości osobistej
>
Jeśli jest true, to równość
zazwyczaj
można wywnioskować logicznie, jeśli obiekt jest sobą, to powinien zostać przetestowany jako równoważny samemu sobie.
W większości przypadków ta logika jest poprawna, ale opiera się na implementacji specjalnej metody . Jak mówią
lekarzy
https://docs.python.org/3/refe ... isons
,
Domyślne zachowanie dla porównań równości ( i ) jest oparte na
tożsamość przedmiotów. Stąd porównanie równości instancji
z tą samą tożsamością prowadzi do równości i porównania równości
instancje z różnymi identyfikatorami powodują nierówności. Jeden
domyślną motywacją do tego zachowania jest pragnienie, aby wszystkie obiekty
musi być odblaskowy (tj. x-y implikuje x == y).
iw trosce o spójność rekomenduje:
Porównania równości powinny być refleksyjne. Innymi słowy, identyczne
obiekty muszą się równać:
implikuje
Widzimy, że jest to domyślne zachowanie dla obiektów niestandardowych:
Zwykle jest również prawdą przeciwstawną - jeśli coś jest testowane jako nierówne, zwykle można wywnioskować, że nie jest to ten sam przedmiot.
Ponieważ testy równości można dostosowywać, wniosek ten nie zawsze jest prawdziwy dla wszystkich typów.
Wyjątek
>
Godnym uwagi wyjątkiem jest - zawsze testuje jako nierówny:
Sprawdzanie tożsamości może być znacznie szybszym sprawdzaniem niż sprawdzanie równości (co może wymagać rekurencyjnego sprawdzania członków).
Ale nie można tego zastąpić równością, gdy można znaleźć więcej niż jeden obiekt jako równoważny.
Zwróć uwagę, że porównanie równości między listami i krotkami zakłada, że obiekty są identyczne (ponieważ jest to szybkie sprawdzenie). Może to powodować sprzeczności, jeśli logika jest niespójna - jak to się dzieje w przypadku :
pouczająca historia:
>
Pytanie próbuje użyć do porównania liczb całkowitych. Nie należy zakładać, że wystąpienie będące liczbą całkowitą jest tym samym wystąpieniem, co wystąpienie uzyskane z innego odwołania. Ta historia wyjaśnia, dlaczego.
Komentator miał kod, który opierał się na fakcie, że małe liczby całkowite (od -5 do 256 włącznie) są singletami w Pythonie, zamiast sprawdzać pod kątem równości.
Wow, może to prowadzić do podstępnych błędów. Miałem kod, który sprawdzał, czy b działa tak, jak chciałem, ponieważ aib to zwykle małe liczby. Błąd pojawił się dopiero dzisiaj, po sześciu miesiącach pracy, ponieważ a i b w końcu były na tyle duże, że nie można ich było buforować. - SHG
To działało podczas rozwoju. Być może przeszedł kilka testów jednostkowych.
I działał w produkcji - dopóki kod nie sprawdził liczby całkowitej większej niż 256, po czym nie udało się go wyprodukować.
Jest to usterka produkcyjna, która mogła zostać wykryta podczas przeglądania kodu lub przy użyciu narzędzia do sprawdzania stylu.
Podkreślę:
nie używaj do porównywania liczb całkowitych.
https://stackoverflow.com/a/28864111/541136
Anonimowy użytkownik
Potwierdzenie od:
Anonimowy użytkownik
Potwierdzenie od:
Jaka jest różnica między a ?
>
i to różne porównania! Jak powiedzieli inni:
W Pythonie nazwy odnoszą się do obiektów, na przykład w tym przypadku i odnoszą się do instancji , która przechowuje wartość :
https://i.stack.imgur.com/WLzXy.png
Ponieważ odnosi się do tego samego obiektu , a da :
W poniższym przykładzie nazwy i odnoszą się do różnych wystąpień , nawet jeśli oba zawierają tę samą liczbę całkowitą:
https://i.stack.imgur.com/IJgBI.png
Ponieważ ta sama wartość (liczba całkowita) jest przechowywana, będzie , dlatego często nazywa się to „porównaniem wartości”. Jednak zwróci wartość , ponieważ są to różne obiekty:
Kiedy i czego używać?
>
Zazwyczaj to znacznie szybsze porównanie. Właśnie dlatego CPython buforuje (lub może lepiej użyć
re
) pewne obiekty, takie jak małe liczby całkowite, niektóre ciągi znaków itp. Ale to powinno być traktowane jako
Szczegóły dotyczące wdrożenia
które mogą (nawet jeśli jest to mało prawdopodobne) zmienić w dowolnym momencie bez ostrzeżenia.
Musisz
użyj tylko ,
Jeśli ty:
[/*]
[/list]
W
w każdym innym przypadku należy użyć
do testowania równości.
Czy mogę dostosować zachowanie?
>
Jest jeszcze jeden aspekt , o którym nie wspomniano wcześniej w innych odpowiedziach: to jest część
Pythons "Data model"
https://docs.python.org/3/refe ... el... Oznacza to, że jego zachowanie można dostosować za pomocą tej metody https://docs.python.org/refere ... __... Na przykład:
To tylko sztuczny przykład ilustrujący, jak nazywa się ta metoda:
Zwróć uwagę, że domyślnie (jeśli w klasie lub nadklasach nie ma innej implementacji ) używa :
Dlatego tak naprawdę ważne jest, aby zaimplementować , jeśli chcesz mieć „więcej”, a nie tylko porównanie referencyjne dla niestandardowych klas!
Z drugiej strony nie można dostosować czeku . Zawsze będzie porównywał
tylko
w przypadku, gdy masz ten sam link.
Czy te porównania zawsze zwracają wartość logiczną?
>
Ponieważ można ponownie zaimplementować lub nadpisać, nie ogranicza się do zwracania lub . To
mogą
zwraca cokolwiek (ale w większości przypadków powinno zwrócić wartość logiczną!).
Na przykład w przypadku tablic NumPy funkcja zwróci tablicę:
Ale lub czeki zawsze zwracają!
<sup>
1
</sup>
Jak wspomniał Aaron Hall w komentarzach:
Generalnie nie należy wykonywać żadnych kontroli lub , ponieważ te sprawdzenia są zwykle używane w kontekście, który niejawnie konwertuje
stan: schorzenie
na wartość logiczną (na przykład w instrukcji ). Zatem porównanie to
i
niejawne rzutowanie boolowskie wykonuje więcej pracy niż tylko rzutowanie boolowskie - i ograniczasz się do wartości logicznych (co nie jest uważane za pythonowe).
Jak wspomina PEP8:
Nie porównuj wartości logicznych z lub za pomocą .
Anonimowy użytkownik
Potwierdzenie od:
zupełnie inaczej
. testuje tożsamość obiektu, podczas gdy testuje równość (pojęcie zależne od typów dwóch operandów).
To po prostu szczęśliwy zbieg okoliczności, że „ ” wydaje się działać poprawnie z małymi liczbami całkowitymi (np. 5 == 4 + 1). To dlatego, że
że CPython optymalizuje przechowywanie liczb całkowitych z zakresu (od -5 do 256), tworząc z nich pojedyncze
https://docs.python.org/2/c-ap ... ng... To zachowanie jest całkowicie zależne od implementacji i nie ma gwarancji, że będzie się utrzymywać we wszystkich rodzajach drobnych operacji transformacji.
Na przykład Python 3.5 również tworzy singlet z krótkich ciągów, ale ich cięcie przerywa to zachowanie:
Anonimowy użytkownik
Potwierdzenie od:
https://docs.python.org/librar ... isons
testy tożsamości testy równości
Każda (mała) wartość całkowita jest mapowana na jedną wartość, więc wszystkie 3 są identyczne i równe. Jest to jednak szczegół implementacji, a nie część specyfikacji języka.
Anonimowy użytkownik
Potwierdzenie od:
Tożsamość przedmiotu nigdy nie zmienia się po jego stworzeniu; możesz o nim myśleć jako o adresie obiektu w pamięci.
Możesz kontrolować zachowanie porównywania wartości obiektów, definiując metodę lub
bogata metoda porównania
https://docs.python.org/refere ... ation
takie jak .
Anonimowy użytkownik
Potwierdzenie od:
Operator „is” w Pythonie zachowuje się nieoczekiwanie w przypadku liczb całkowitych
https://coderoad.ru/306313/
liczby.
Zasadniczo sprowadza się to do tego, że „ ” sprawdza, czy są to ten sam obiekt, a nie tylko sobie równe (liczby poniżej 256 to przypadek specjalny).
Anonimowy użytkownik
Potwierdzenie od:
Anonimowy użytkownik
Potwierdzenie od:
Istnieje jedno i tylko jedno wystąpienie NoneType, to znaczy żadne z nich nie jest singletonem. Dlatego i oznaczają to samo. Jednak test jest szybszy, a konwencją aktualizacji jest użycie .
Jeśli robisz jakąś introspekcję lub bawisz się przy usuwaniu elementów bezużytecznych lub sprawdzasz, czy Twój niestandardowy gadżet internowania ciągów działa, czy coś w tym stylu, prawdopodobnie masz przypadek użycia dla .
True i False są również (teraz) singletami, ale nie ma przypadku użycia dla , a dla .
Anonimowy użytkownik
Potwierdzenie od:
Operator is może wydawać się taki sam jak operator równości, ale
to nie to samo.
Sprawdza, czy obie zmienne wskazują na ten sam obiekt, podczas gdy
sign = = sprawdza, czy wartości dwóch zmiennych są takie same.
Jeśli więc operator zwraca True, to równość jest zdecydowanie
To prawda, że sytuacja odwrotna może być prawdą lub nie.
Oto przykład pokazujący podobieństwa i różnice.
Anonimowy użytkownik
Potwierdzenie od:
==, jeśli obiekty, do których odwołują się zmienne, są równe
z góry odpowiedzi należy czytać tak:
==, jeśli obiekty, do których odwołują się zmienne, są równe i należą do tego samego typu/klasy .
Doszedłem do tego wniosku na podstawie poniższego testu:
Tutaj zawartość listy i krotki jest taka sama, ale typ/klasa jest inny.
Anonimowy użytkownik
Potwierdzenie od:
położyć nacisk
głównie porównanie między a
na smyczki
co może dawać różne wyniki i zachęcałbym programistów do ostrożnego ich używania.
Aby porównać ciągi, użyj zamiast :
Z:
Ale
w poniższym przykładzie i dadzą różne wyniki:
Z:
Wynik
:
Używaj ostrożnie do porównań ciągów