Czy jest różnica między " = = "A " is"?
Moje Google-fu zawiodło mnie.
W Pythonie, czy 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 to prawda dla obiektów, w których porównujesz instancje (a list
powiedzmy)?
Ok, więc taki rodzaj odpowiedzi na moje pytanie:
L = []
L.append(1)
if L == [1]:
print 'Yay!'
# Holds true, but...
if L is [1]:
print 'Yay!'
# Doesn't.
Więc ==
testuje wartość gdzie is
testuje, czy są tym samym obiektem?
14 answers
is
zwróci True
Jeśli dwie zmienne wskazują na ten sam obiekt, {[5] } jeśli obiekty, do których odnoszą się zmienne, są równe.
>>> a = [1, 2, 3]
>>> b = a
>>> b is a
True
>>> b == a
True
# Make a new copy of list `a` via the slice operator,
# and assign it to variable `b`
>>> b = a[:]
>>> b is a
False
>>> b == a
True
W Twoim przypadku drugi test działa tylko dlatego, że Python buforuje małe obiekty całkowite, co jest szczegółem implementacji. Dla większych liczb całkowitych to nie działa:
>>> 1000 is 10**3
False
>>> 1000 == 10**3
True
To samo dotyczy liter ciągów:
>>> "a" is "a"
True
>>> "aa" is "a" * 2
True
>>> x = "a"
>>> "aa" is x * 2
False
>>> "aa" is intern(x*2)
True
Proszę zobaczyćto pytanie również.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-11-05 20:47:38
Istnieje prosta zasada mówiąca, kiedy należy stosować ==
lub is
.
-
==
jest dla równość wartości . Użyj go, gdy chcesz wiedzieć, czy dwa obiekty mają tę samą wartość. -
is
oznacza równość odniesienia. Użyj go, gdy chcesz wiedzieć, czy dwa odniesienia odnoszą się do tego samego obiektu.
Ogólnie rzecz biorąc, kiedy porównujesz coś z prostym typem, Zwykle sprawdzasz równość wartości, więc należy użyć ==
. Na przykład, intencją twojego przykładu jest prawdopodobnie sprawdzenie, czy x ma wartość równą 2 (==
), a nie czy x
odnosi się dosłownie do tego samego obiektu co 2.
Coś jeszcze do odnotowania: ze względu na sposób, w jaki implementacja CPython reference działa, otrzymasz nieoczekiwane i niespójne wyniki, jeśli błędnie użyjesz is
do porównania równości referencji na liczbach całkowitych:
>>> a = 500
>>> b = 500
>>> a == b
True
>>> a is b
False
Tego się spodziewaliśmy: a
i b
mają tej samej wartości, ale są odrębnymi bytami. Ale co z tym?
>>> c = 200
>>> d = 200
>>> c == d
True
>>> c is d
True
Jest to niezgodne z wcześniejszym wynikiem. Co tu się dzieje? Okazuje się, że referencyjna implementacja Pythona buforuje obiekty całkowite w zakresie -5..256 jako instancje singleton ze względu na wydajność. Oto przykład demonstrujący to:
>>> for i in range(250, 260): a = i; print "%i: %s" % (i, a is int(str(i)));
...
250: True
251: True
252: True
253: True
254: True
255: True
256: True
257: False
258: False
259: False
Jest to kolejny oczywisty powód, aby nie używać is
: zachowanie jest pozostawione do implementacji, gdy błędnie używasz go dla wartości równość.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-01-03 02:09:38
Tak, mają bardzo ważną różnicę.Czy jest różnica między
==
ais
w Pythonie?
==
: sprawdzanie 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. Jak mówi dokumentacja :
Operatory , ==, >=,
is
: check for identity-the semantyka polega na tym, że obiekt (przechowywany w pamięci) jest obiektem. Ponownie, dokumentacja mówi :
Operatory
is
iis not
sprawdzają tożsamość obiektu:x is y
jest prawdą wtedy i tylko wtedy, gdyx
iy
są tym samym obiektem. Tożsamość obiektu jest określone za pomocą funkcjiid()
.x is not y
daje odwrotność wartość prawdy.
Tak więc sprawdzanie tożsamości jest tym samym, co sprawdzanie równości ID obiektów. Że is,
a is b
Jest tym samym co:
id(a) == id(b)
Gdzie {[16] } jest wbudowaną funkcją zwracającą liczbę całkowitą, która "jest gwarantowana jako unikalna wśród jednocześnie istniejących obiektów" (zobacz help(id)
) i gdzie a
i b
są dowolnymi dowolnymi obiektami.
Inne Wskazówki Użytkowania
Powinieneś użyć tych porównań do ich semantyki. Użyj is
, aby sprawdzić tożsamość i ==
, aby sprawdzić równość.
Więc ogólnie używamy is
, aby sprawdzić tożsamość. To jest zwykle przydatne, gdy sprawdzamy obiekt, który powinien istnieć tylko raz w pamięci, określany w dokumentacji jako "singleton".
Przypadki użycia dla is
obejmują:
None
- wartości enum (przy użyciu Enum z modułu enum)
- Zwykle Moduły
- Zwykle obiekty klasy wynikające z definicji klasy
- Zwykle obiekty funkcyjne wynikające z definicji funkcji
- Wszystko inne, co powinno istnieć tylko raz w pamięć (wszystkie singletony, ogólnie)
- konkretny obiekt, który chcesz przez tożsamość
Typowe przypadki użycia dla ==
obejmują:
- liczby, łącznie z liczbami całkowitymi
- struny
- listy
- zestawy
- słowniki
- niestandardowe mutable objects
- inne wbudowane niezmienne obiekty, w większości przypadków
Ogólny przypadek użycia, ponownie, dla ==
, jest obiektem, który chcesz, może nie być tym samym obiektem, zamiast może to być odpowiednik jeden
PEP 8 kierunków
PEP 8, oficjalny przewodnik po stylach Pythona dla biblioteki standardowej wymienia również dwa przypadki użycia dla is
:
Porównania do singletonów jak
None
powinny być zawsze wykonywaneis
lubis not
, Nigdy operatorów równości.Także, uważaj na pisanie
if x
kiedy naprawdę masz na myśliif x is not None
-- na przykład podczas testowania, czy zmienna lub argument domyślnieNone
na Ustaw na inną wartość. Druga wartość może mieć typ (taki jako kontener), które mogą być fałszywe w kontekście logicznym!
Wnioskowanie równości z tożsamości
Jeśli is
jest prawdą, równość może Zwykle być wywnioskowana - logicznie, jeśli obiekt jest sam w sobie, to powinien testować jako jego odpowiednik.
W większości przypadków ta logika jest prawdziwa, ale opiera się na implementacji specjalnej metody __eq__
. Jak mówią docs
Domyślne zachowanie porównywania równości (
==
i!=
) opiera się na tożsamość przedmiotów. Stąd porównanie równości instancji z tą samą tożsamością wynika równość, a równość instancje o różnych tożsamościach powodują nierówność. A motywacją do tego domyślnego zachowania jest pragnienie, aby wszystkie obiekty powinien być refleksyjny (tzn. x jest Y oznacza x = = y).
I w trosce o spójność, zaleca:
Porównanie równości powinno być refleksyjne. Innymi słowy, identyczne obiekty powinny być równe:
x is y
implikujex == y
Widzimy, że jest to domyślne zachowanie dla obiektów niestandardowych:
>>> class Object(object): pass
>>> obj = Object()
>>> obj2 = Object()
>>> obj == obj, obj is obj
(True, True)
>>> obj == obj2, obj is obj2
(False, False)
Contrapositive jest również zwykle prawdziwe - jeśli coś testuje się jako nie równe, zwykle można wywnioskować, że nie są one tym samym obiektem.
Ponieważ testy równości można dostosować, wniosek ten nie zawsze jest prawdziwy dla wszystkich typy.
Wyjątek
Godnym uwagi wyjątkiem jest nan
- zawsze sprawdza się jako nie równy sobie:
>>> nan = float('nan')
>>> nan
nan
>>> nan is nan
True
>>> nan == nan # !!!!!
False
Sprawdzanie tożsamości może być znacznie szybsze niż sprawdzanie równości (które może wymagać rekurencyjnego sprawdzania członków).
Ale nie można go zastąpić równością, gdzie można znaleźć więcej niż jeden obiekt jako równoważny.
Zauważ, że porównywanie równości list i krotek zakłada, że tożsamość obiektów jest równa (ponieważ jest to szybka kontrola). Może to tworzyć sprzeczności, jeśli logika jest niespójna - tak jak dla nan
:
>>> [nan] == [nan]
True
>>> (nan,) == (nan,)
True
Przestroga:
Pytanie próbuje użyć is
do porównania liczb całkowitych. Nie należy zakładać, że instancja liczby całkowitej jest tą samą instancją co instancja uzyskana przez inne odniesienie. 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ą singletonami w Pythonie, zamiast sprawdzanie równości.
To może prowadzić do podstępnych błędów. Miałem jakiś kod, który sprawdzał, czy a jest b, który działał tak, jak chciałem, ponieważ a i b są zazwyczaj małymi liczbami. Błąd pojawił się dopiero dzisiaj, po sześciu miesiącach produkcji, ponieważ a i b były na tyle duże, że nie mogły być buforowane. - gwg
To działało w rozwoju. Mógł przejść kilka testów.
I działało w produkcji-dopóki kod nie sprawdzał liczby całkowitej większej niż 256, w którym to momencie nie udało się w produkcji.
Jest to błąd produkcyjny, który mógł zostać złapany w przeglądaniu kodu lub ewentualnie za pomocą sprawdzania stylów.
Pozwól, że podkreślę: nie używaj is
do porównywania liczb całkowitych.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-02-10 18:31:09
==
określa, czy wartości są równe, podczas gdy is
określa, czy są dokładnie tym samym obiektem.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-05-27 12:36:36
Jaka jest różnica między is
a ==
?
==
i is
są różne porównania! Jak już powiedzieli inni:
-
==
porównuje wartości obiektów. -
is
porównuje odniesienia do obiektów.
W Pythonie nazwy odnoszą się do obiektów, na przykład w tym przypadku value1
i value2
odnoszą się do instancji int
przechowującej wartość 1000
:
value1 = 1000
value2 = value1
Ponieważ value2
odnosi się do tego samego obiektu is
i ==
daTrue
:
>>> value1 == value2
True
>>> value1 is value2
True
W poniższym przykładzie nazwy value1
i value2
odnoszą się do różnych instancji int
, nawet jeśli oba zawierają tę samą liczbę całkowitą:
>>> value1 = 1000
>>> value2 = 1000
Ponieważ ta sama wartość (liczba całkowita) jest przechowywana ==
będzie True
, dlatego często nazywa się ją "porównaniem wartości". Jednak is
zwróci False
ponieważ są to różne obiekty:
>>> value1 == value2
True
>>> value1 is value2
False
Kiedy użyć którego?
Ogólnie is
jest znacznie szybszym porównanie. Dlatego CPython buforuje (a może reuses byłoby lepszym określeniem) pewne obiekty, takie jak małe liczby całkowite, niektóre łańcuchy znaków itp. Ale to powinno być traktowane jako szczegóły implementacji , które mogą (nawet jeśli mało prawdopodobne) zmienić się w dowolnym momencie bez ostrzeżenia.
Powinieneś używać tylko is
jeśli:
-
Chcesz sprawdzić, czy dwa obiekty są rzeczywiście tym samym obiektem (nie tylko tą samą "wartością"). Jednym z przykładów może być, jeśli ty używasz obiekt Singletona jako stały.
-
Chcesz porównać wartość do Pythona stałej. Stałe w Pythonie to:
None
-
True
1 -
False
1 NotImplemented
Ellipsis
__debug__
- klasy (na przykład
int is int
lubint is float
) - mogą istnieć dodatkowe stałe we wbudowanych modułach lub modułach innych firm. Na przykład
np.ma.masked
od NumPy moduł)
W w każdym innym przypadku należy użyć ==
aby sprawdzić równość.
Czy Mogę dostosować zachowanie?
Jest pewien aspekt ==
, który nie został wymieniony jeszcze w innych odpowiedziach: jest częścią Pythons "model danych" . Oznacza to, że jego zachowanie można dostosować za pomocą __eq__
metoda. Na przykład:
class MyClass(object):
def __init__(self, val):
self._value = val
def __eq__(self, other):
print('__eq__ method called')
try:
return self._value == other._value
except AttributeError:
raise TypeError('Cannot compare {0} to objects of type {1}'
.format(type(self), type(other)))
Jest to tylko sztuczny przykład, aby zilustrować, że metoda jest naprawdę nazwa:
>>> MyClass(10) == MyClass(10)
__eq__ method called
True
Zauważ, że domyślnie (jeśli żadna inna implementacja __eq__
nie może być znaleziona w klasie lub superklasach) __eq__
używa is
:
class AClass(object):
def __init__(self, value):
self._value = value
>>> a = AClass(10)
>>> b = AClass(10)
>>> a == b
False
>>> a == a
Dlatego ważne jest, aby zaimplementować __eq__
jeśli chcesz "więcej" niż tylko porównywanie referencji dla klas niestandardowych!
Z drugiej strony nie można dostosować is
kontroli. Zawsze będzie porównywać tylko , jeśli masz to samo odniesienie.
Czy te porównania zawsze zwrócą boolean?
Ponieważ __eq__
może być ponownie zaimplementowany lub nadpisany, nie ogranicza się do zwracania True
lub False
. To może zwrócić cokolwiek (ale w większości przypadków powinno zwrócić wartość logiczną!).
Na przykład z tablicami NumPy ==
zwróci tablicę:
>>> import numpy as np
>>> np.arange(10) == 2
array([False, False, True, False, False, False, False, False, False, False], dtype=bool)
Ale is
kontrole zawsze wrócą True
lub False
!
1 jak wspomniał Aaron Hall w komentarzach:
Ogólnie nie powinieneś robić żadnych is True
lub is False
kontroli ponieważ zwykle używa się tych "sprawdzeń" w kontekście, który domyślnie konwertuje warunek na wartość logiczną (na przykład w instrukcji if
). Tak więc wykonanie porównania is True
i Ukryty boolean cast wykonuje więcej pracy niż tylko wykonanie boolean cast - i ograniczasz się do booleanów (co nie jest uważane za pythoniczne).
Jak PEP8 wspomina:
Nie porównuj wartości logicznych do
True
lubFalse
używając==
.Yes: if greeting: No: if greeting == True: Worse: if greeting is True:
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-06-20 09:12:55
Są zupełnie inne . is
sprawdza tożsamość obiektu, podczas gdy ==
sprawdza równość(pojęcie, które zależy od dwóch typów operandów).
To tylko szczęśliwy zbieg okoliczności, że "is
" wydaje się działać poprawnie z małymi liczbami całkowitymi (np. 5 == 4+1). Jest tak, ponieważ CPython optymalizuje przechowywanie liczb całkowitych w zakresie (-5 do 256), tworząc z nich singletony. Zachowanie to jest całkowicie zależne od implementacji i nie gwarantuje zachowania pod wszelkiego rodzaju drobnych operacji transformacyjnych.
Na przykład Python 3.5 również tworzy krótkie stringi singletonów, ale ich przecięcie zakłóca to zachowanie:
>>> "foo" + "bar" == "foobar"
True
>>> "foo" + "bar" is "foobar"
True
>>> "foo"[:] + "bar" == "foobar"
True
>>> "foo"[:] + "bar" is "foobar"
False
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-07-10 15:14:22
Https://docs.python.org/library/stdtypes.html#comparisons
is
testy na tożsamość
==
testy równości
Każda (mała) liczba całkowita jest mapowana do pojedynczej wartości, więc każde 3 jest identyczne i równe. Jest to szczegół implementacji, a nie część specyfikacji języka
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-11-13 10:02:19
Twoja odpowiedź jest prawidłowa. Operator is
porównuje tożsamość dwóch obiektów. Operator ==
porównuje wartości dwóch obiektów.
Tożsamość obiektu nigdy nie zmienia się po jego utworzeniu; możesz myśleć o nim jako o adresie obiektu w pamięci.
Możesz kontrolować zachowanie porównywania wartości obiektu poprzez zdefiniowanie metody __cmp__
lub metodyrich comparison , takiej jak __eq__
.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-11-13 09:24:18
Spójrz na pytanie o przepełnienie stosu Operator Pythona " is " zachowuje się nieoczekiwanie z liczbami całkowitymi.
Sprowadza się to głównie do tego, że "is
" sprawdza, czy są one tym samym obiektem, a nie tylko równym sobie (liczby poniżej 256 są szczególnym przypadkiem).
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 10:31:38
W skrócie, is
sprawdza, czy dwa odniesienia wskazują na ten sam obiekt, czy nie.==
sprawdza, czy dwa obiekty mają tę samą wartość, czy nie.
a=[1,2,3]
b=a #a and b point to the same object
c=list(a) #c points to different object
if a==b:
print('#') #output:#
if a is b:
print('##') #output:##
if a==c:
print('###') #output:##
if a is c:
print('####') #no output as c and a point to different object
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-07-29 20:17:41
Jak powiedział John Feminella, większość czasu będziesz używać = = i != ponieważ twoim celem jest porównanie wartości. Chciałbym tylko skategoryzować co byś robił przez resztę czasu:
Istnieje tylko jedna instancja NoneType, tzn. None jest singletonem. W konsekwencji foo == None
i foo is None
oznaczają to samo. Jednak test is
jest szybszy, a konwencja Pythoniczna ma używać foo is None
.
Jeśli robisz jakąś introspekcję lub robisz coś ze śmieciami lub sprawdzasz, czy Twój niestandardowy gadżet do internowania ciągów działa lub coś takiego, prawdopodobnie masz przypadek użycia dla foo
jest bar
.
True I False są również (teraz) singletonami, ale nie ma przypadków użycia dla foo == True
i nie ma przypadków użycia dla foo is True
.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-07-06 08:50:52
Większość z nich już odpowiedziała na to pytanie. Tylko jako dodatkowa uwaga (na podstawie mojego zrozumienia i eksperymentowania, ale nie z udokumentowanego źródła), stwierdzenie
= = jeśli obiekty, do których odnoszą się zmienne, są równe
Z powyższych odpowiedzi należy odczytać jako
= = jeśli obiekty, do których odnoszą się zmienne, są równe i obiekty należące do tego samego typu / klasy
. Doszedłem do tego wniosku na podstawie poniższego test:
list1 = [1,2,3,4]
tuple1 = (1,2,3,4)
print(list1)
print(tuple1)
print(id(list1))
print(id(tuple1))
print(list1 == tuple1)
print(list1 is tuple1)
Tutaj zawartość listy i krotki są takie same, ale Typ / Klasa są inne.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-03-07 08:05:20
Różnica w Pythonie pomiędzy is I equals (==)
Operator is może wydawać się taki sam jak operator równości, ale nie są takie same.
Is sprawdza, czy obie zmienne wskazują na ten sam obiekt, podczas gdy znak = = sprawdza, czy wartości obu zmiennych są takie same.
Więc jeśli operator is zwraca True to równość jest definitywna Prawda, ale odwrotnie może być, ale nie musi być prawdą.
Oto przykład do zademonstrowania podobieństwo i różnica.
>>> a = b = [1,2,3]
>>> c = [1,2,3]
>>> a == b
True
>>> a == c
True
>>> a is b
True
>>> a is c
False
>>> a = [1,2,3]
>>> b = [1,2]
>>> a == b
False
>>> a is b
False
>>> del a[2]
>>> a == b
True
>>> a is b
False
Tip: Avoid using is operator for immutable types such as strings and numbers, the result is unpredictable.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-08-08 12:30:33
Jako, że inni ludzie w tym poście odpowiadają na pytanie szczegółowo różnica między ==
i is
do porównywania obiektów lub zmiennych, chciałbym podkreślić głównie porównanie między is
i ==
dla ciągów , które mogą dawać różne wyniki i zachęcam programistów do uważnego ich używania.
Dla porównania łańcuchów, upewnij się, że używasz ==
zamiast is
:
str = 'hello'
if (str is 'hello'):
print ('str is hello')
if (str == 'hello'):
print ('str == hello')
Out:
str is hello
str == hello
Ale W poniższym przykładzie ==
i is
otrzymają różne wyniki:
str2 = 'hello sam'
if (str2 is 'hello sam'):
print ('str2 is hello sam')
if (str2 == 'hello sam'):
print ('str2 == hello sam')
Out:
str2 == hello sam
Wnioski i analizy:
Użyj is
ostrożnie, aby porównać między łańcuchami.
Ponieważ is
do porównywania obiektów i ponieważ w Pythonie 3+ każda zmienna, taka jak string, interpretuje jako obiekt, zobaczmy, co się stało w powyższych akapitach.
W Pythonie jest id
funkcja, która pokazuje unikalną stałą obiektu podczas jego życia. Ten identyfikator jest używany w back-endzie Pythona interpreter porównujący dwa obiekty za pomocą słowa kluczowego is
.
str = 'hello'
id('hello')
> 140039832615152
id(str)
> 140039832615152
Ale
str2 = 'hello sam'
id('hello sam')
> 140039832615536
id(str2)
> 140039832615792
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-06-21 01:40:51