Gibt es einen Unterschied zwischen "==" und "ist"?


630

Mein Google-Fu hat mich gescheitert.

Sind in Python die folgenden zwei Tests auf Gleichheit gleichwertig?

n = 5
# Test one.
if n == 5:
    print 'Yay!'

# Test two.
if n is 5:
    print 'Yay!'

Gilt dies für Objekte, bei denen Sie Instanzen vergleichen würden (ein listMitspracherecht)?

Okay, diese Art beantwortet meine Frage:

L = []
L.append(1)
if L == [1]:
    print 'Yay!'
# Holds true, but...

if L is [1]:
    print 'Yay!'
# Doesn't.

So ==testet Wert , bei dem isüberprüft, ob sie das gleiche Objekt sind?

Antworten:


926

iswird zurückgegeben, Truewenn zwei Variablen auf dasselbe Objekt zeigen, ==wenn die Objekte, auf die sich die Variablen beziehen, gleich sind.

>>> 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

In Ihrem Fall funktioniert der zweite Test nur, weil Python kleine Ganzzahlobjekte zwischenspeichert, was ein Implementierungsdetail darstellt. Bei größeren Ganzzahlen funktioniert dies nicht:

>>> 1000 is 10**3
False
>>> 1000 == 10**3
True

Gleiches gilt für String-Literale:

>>> "a" is "a"
True
>>> "aa" is "a" * 2
True
>>> x = "a"
>>> "aa" is x * 2
False
>>> "aa" is intern(x*2)
True

Bitte beachten Sie auch diese Frage .


2
Ich fand das: echo 'import sys;tt=sys.argv[1];print(tt is "foo", tt == "foo", id(tt)==id("foo"))'| python3 - fooAusgabe : False True False.
Ahuigo

Sie haben mich mit dem b = a[:]Kopierteil der Slice-Operator-Liste verloren, daher habe ich Ihre Antwort bearbeitet, um dort einen Kommentar zu erhalten. Es sieht so aus, als hätte ich gerade den Schwellenwert erreicht, um meine Änderungen nicht überprüfen zu müssen, bevor sie angewendet werden. Hoffentlich ist das cool für Sie. Unabhängig davon, hier ist eine nützliche Referenz zum Kopieren von Listen, auf die ich gestoßen
Gabriel Staples

Eine andere Möglichkeit, den Unterschied zu demonstrieren, besteht darin, Objekte verschiedener Typen zu vergleichen, die natürlich niemals dasselbe Objekt sein können, aber bei Verwendung immer noch gleich sind ==. So ist 5.0beispielsweise ein Gleitkommawert, während 5es sich um eine Ganzzahl handelt. Aber 5.0 == 5immer noch zurückkehren , Trueweil sie den gleichen Wert darstellen. In Bezug auf Leistung und isEntentypisierung wird der Interpreter immer durch Vergleichen der Speicheradressen des Operanden getestet, während ==es dem Objekt überlassen bleibt, zu entscheiden, ob es sich selbst als gleichwertig mit etwas anderem definiert.
Bachsau

3
1000 is 10**3wird in Python 3.7 als True ausgewertet, da 10 ** 3 vom Typ ist int. 1000 is 1e3Wird aber als falsch ausgewertet, da 1e3 vom Typ ist float.
Ahmed Fasih

@AhmedFasih Ob dies 1000 is 10**3zutrifft oder nicht , hängt von der Implementierung ab und hängt davon ab, ob der Compiler den Ausdruck vorab auswertet 10**3. x=10; 1000 is x**3bewertet zu False.
Chepner

311

Es gibt eine einfache Faustregel, die Ihnen sagt, wann Sie ==oder verwenden sollen is.

  • ==ist für Wertgleichheit . Verwenden Sie diese Option, wenn Sie wissen möchten, ob zwei Objekte denselben Wert haben.
  • isist als Referenzgleichheit . Verwenden Sie diese Option, wenn Sie wissen möchten, ob sich zwei Referenzen auf dasselbe Objekt beziehen.

Im Allgemeinen, wenn Sie etwas auf eine einfache Art vergleichen, werden Sie in der Regel der Überprüfung für Wertgleichheit , so sollten Sie verwenden ==. In Ihrem Beispiel soll beispielsweise geprüft werden, ob x einen Wert von 2 ( ==) hat und nicht, ob xes sich buchstäblich auf dasselbe Objekt wie 2 bezieht.


Noch etwas zu beachten: Aufgrund der Funktionsweise der CPython-Referenzimplementierung erhalten Sie unerwartete und inkonsistente Ergebnisse, wenn Sie fälschlicherweise die isVergleichsgleichheit für Ganzzahlen verwenden:

>>> a = 500
>>> b = 500
>>> a == b
True
>>> a is b
False

Das ist ziemlich genau das, was wir erwartet haben: aund bhaben den gleichen Wert, sind aber unterschiedliche Einheiten. Aber was ist damit?

>>> c = 200
>>> d = 200
>>> c == d
True
>>> c is d
True

Dies stimmt nicht mit dem früheren Ergebnis überein. Was ist denn hier los? Es stellt sich heraus, dass die Referenzimplementierung von Python-Cache-Integer-Objekten im Bereich -5..256 aus Leistungsgründen als Singleton-Instanzen zwischengespeichert wird. Hier ist ein Beispiel, das dies demonstriert:

>>> 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

Dies ist ein weiterer offensichtlicher Grund, den Sie nicht verwenden sollten is: Das Verhalten bleibt den Implementierungen überlassen, wenn Sie es fälschlicherweise für die Wertgleichheit verwenden.


In Bezug auf das erste Beispiel von a=500und b=500wollte ich nur darauf hinweisen, dass, wenn Sie aund bauf einen Interger zwischen [-5, 256] setzen, a is btatsächlich zurückkehrt True. Weitere Informationen hier: stackoverflow.com/q/306313/7571052
AsheKetchum

1
@AsheKetchum, ja, beachten Sie, dass ich geschrieben habe: "Es stellt sich heraus, dass die Referenzimplementierung von Python-Cache-Integer-Objekten im Bereich -5..256 aus Leistungsgründen als Singleton-Instanzen zwischengespeichert wird."
John Feminella

34

==bestimmt, ob die Werte gleich sind, während isbestimmt, ob sie genau dasselbe Objekt sind.


32

Gibt es einen Unterschied zwischen ==und isin Python?

Ja, sie haben einen sehr wichtigen Unterschied.

==: auf Gleichheit prüfen - Die Semantik lautet, dass äquivalente Objekte (die nicht unbedingt dasselbe Objekt sind) als gleich getestet werden. Wie die Dokumentation sagt :

Die Operatoren <,>, ==,> =, <= und! = Vergleichen die Werte zweier Objekte.

is: Identitätsprüfung - Die Semantik lautet, dass das Objekt (wie im Speicher gespeichert) das Objekt ist. Wieder heißt es in der Dokumentation :

Die Betreiber isund is notTest für die Objektidentität: x is yist wahr , wenn und nur wenn xund ydasselbe Objekt sind. Die Objektidentität wird mit der id()Funktion ermittelt. x is not yergibt den inversen Wahrheitswert.

Somit ist die Überprüfung auf Identität dieselbe wie die Überprüfung auf die Gleichheit der IDs der Objekte. Das ist,

a is b

ist das gleiche wie:

id(a) == id(b)

Wo idist die eingebaute Funktion, die eine Ganzzahl zurückgibt, die "garantiert unter gleichzeitig vorhandenen Objekten eindeutig ist" (siehe help(id)) und wo aund bsind beliebige Objekte.

Andere Verwendungshinweise

Sie sollten diese Vergleiche für ihre Semantik verwenden. Verwenden Sie isdiese Option , um die Identität und ==die Gleichheit zu überprüfen.

Im Allgemeinen isüberprüfen wir daher die Identität. Dies ist normalerweise nützlich, wenn wir nach einem Objekt suchen, das nur einmal im Speicher vorhanden sein sollte und in der Dokumentation als "Singleton" bezeichnet wird.

Anwendungsfälle für isumfassen:

  • None
  • Aufzählungswerte (bei Verwendung von Aufzählungen aus dem Aufzählungsmodul)
  • in der Regel Module
  • normalerweise Klassenobjekte, die aus Klassendefinitionen resultieren
  • normalerweise Funktionsobjekte, die sich aus Funktionsdefinitionen ergeben
  • alles andere, was nur einmal im Speicher existieren sollte (alle Singletons im Allgemeinen)
  • ein bestimmtes Objekt, das Sie nach Identität möchten

Übliche Anwendungsfälle für ==:

  • Zahlen, einschließlich Ganzzahlen
  • Saiten
  • Listen
  • setzt
  • Wörterbücher
  • benutzerdefinierte veränderbare Objekte
  • in den meisten Fällen andere eingebaute unveränderliche Objekte

Die allgemeine Verwendung Fall wieder, denn ==ist das Objekt , das Sie möglicherweise nicht das sein wollen gleiche Objekt, sondern kann es eine sein Äquivalent ein

PEP 8 Richtungen

PEP 8, der offizielle Python-Styleguide für die Standardbibliothek, erwähnt außerdem zwei Anwendungsfälle füris :

Vergleiche mit Singletons wie Nonesollten immer mit isoder is notniemals mit den Gleichheitsoperatoren durchgeführt werden.

Achten if xSie auch darauf, nicht zu schreiben, wenn Sie es wirklich meinen if x is not None- z. B. wenn Sie testen, ob eine Variable oder ein Argument, das standardmäßig verwendet wird, None auf einen anderen Wert gesetzt wurde. Der andere Wert hat möglicherweise einen Typ (z. B. einen Container), der in einem booleschen Kontext falsch sein kann!

Gleichheit aus Identität ableiten

Wenn dies iszutrifft, kann normalerweise auf Gleichheit geschlossen werden. Wenn ein Objekt selbst ist, sollte es logischerweise als gleichwertig mit sich selbst getestet werden.

In den meisten Fällen ist diese Logik richtig, sie beruht jedoch auf der Implementierung der __eq__speziellen Methode. Wie die Dokumente sagen,

Das Standardverhalten für den Gleichheitsvergleich ( ==und !=) basiert auf der Identität der Objekte. Daher führt der Gleichheitsvergleich von Instanzen mit derselben Identität zu Gleichheit, und der Gleichheitsvergleich von Instanzen mit unterschiedlichen Identitäten führt zu Ungleichheit. Eine Motivation für dieses Standardverhalten ist der Wunsch, dass alle Objekte reflexiv sein sollten (dh x ist y impliziert x == y).

und im Interesse der Konsistenz empfiehlt:

Der Gleichstellungsvergleich sollte reflexiv sein. Mit anderen Worten, identische Objekte sollten gleich sein:

x is y impliziert x == y

Wir können sehen, dass dies das Standardverhalten für benutzerdefinierte Objekte ist:

>>> class Object(object): pass
>>> obj = Object()
>>> obj2 = Object()
>>> obj == obj, obj is obj
(True, True)
>>> obj == obj2, obj is obj2
(False, False)

Das Kontrapositive ist normalerweise auch wahr - wenn etwas als nicht gleich getestet wird, können Sie normalerweise schließen, dass es nicht dasselbe Objekt ist.

Da Gleichheitstests angepasst werden können, gilt diese Schlussfolgerung nicht immer für alle Typen.

Eine Ausnahme

Eine bemerkenswerte Ausnahme ist nan- es testet immer als nicht gleich sich selbst:

>>> nan = float('nan')
>>> nan
nan
>>> nan is nan
True
>>> nan == nan           # !!!!!
False

Das Überprüfen der Identität kann viel schneller sein als das Überprüfen der Gleichheit (was möglicherweise eine rekursive Überprüfung der Mitglieder erfordert).

Gleichheit kann jedoch nicht ersetzt werden, wenn Sie möglicherweise mehr als ein Objekt als gleichwertig finden.

Beachten Sie, dass beim Vergleich der Gleichheit von Listen und Tupeln davon ausgegangen wird, dass die Identität von Objekten gleich ist (da dies eine schnelle Überprüfung ist). Dies kann zu Widersprüchen führen, wenn die Logik inkonsistent ist - wie für nan:

>>> [nan] == [nan]
True
>>> (nan,) == (nan,)
True

Eine warnende Geschichte:

Die Frage versucht, isganze Zahlen zu vergleichen. Sie sollten nicht davon ausgehen, dass eine Instanz einer Ganzzahl dieselbe Instanz ist wie eine, die von einer anderen Referenz erhalten wurde. Diese Geschichte erklärt warum.

Ein Kommentator hatte Code, der sich auf die Tatsache stützte, dass kleine Ganzzahlen (-5 bis einschließlich 256) in Python Singletons sind, anstatt auf Gleichheit zu prüfen.

Wow, das kann zu heimtückischen Fehlern führen. Ich hatte einen Code, der überprüfte, ob a b ist, was wie gewünscht funktionierte, da a und b normalerweise kleine Zahlen sind. Der Fehler trat erst heute nach sechs Monaten in der Produktion auf, weil a und b endlich groß genug waren, um nicht zwischengespeichert zu werden. - gwg

Es hat in der Entwicklung funktioniert. Es kann einige Unittests bestanden haben.

Und es funktionierte in der Produktion - bis der Code nach einer ganzen Zahl größer als 256 suchte und zu diesem Zeitpunkt in der Produktion fehlschlug.

Dies ist ein Produktionsfehler, der bei der Codeüberprüfung oder möglicherweise mit einem Style-Checker aufgetreten sein könnte.

Lassen Sie mich betonen: Verwenden Sie nicht is, um ganze Zahlen zu vergleichen.


"überhaupt nicht benutzen" wäre auch eine gute Regel. Die Redewendung is Noneist eine Ausnahme, aber das Gesagte == Nonefunktioniert auch ...
Jean-François Fabre

@ Jean-FrançoisFabre Eine weitere Ausnahme: Die offizielle Dokumentation scheint die Verwendung iszum Vergleichen von Enums zu empfehlen .
Arthur

@Arthur Ich habe eine Liste von Anwendungsfällen hinzugefügt ...
Aaron Hall

19

Was ist der Unterschied zwischen isund ==?

==und issind andere Vergleich! Wie andere bereits sagten:

  • == vergleicht die Werte der Objekte.
  • is vergleicht die Referenzen der Objekte.

In Python beziehen sich Namen beispielsweise in diesem Fall auf Objekte value1und value2auf eine intInstanz, in der der Wert gespeichert ist 1000:

value1 = 1000
value2 = value1

Geben Sie hier die Bildbeschreibung ein

Weil value2bezieht sich auf das gleiche Objekt isund ==wird geben True:

>>> value1 == value2
True
>>> value1 is value2
True

Im folgenden Beispiel beziehen sich die Namen value1und value2Verweise auf verschiedene intInstanzen, auch wenn beide dieselbe Ganzzahl speichern:

>>> value1 = 1000
>>> value2 = 1000

Geben Sie hier die Bildbeschreibung ein

Da der gleiche Wert (Ganzzahl) gespeichert ==wird, Truewird er häufig als "Wertevergleich" bezeichnet. Allerdings iswird zurückkehren , Falseda diese unterschiedliche Objekte sind:

>>> value1 == value2
True
>>> value1 is value2
False

Wann welche verwenden?

Im Allgemeinen isist ein viel schnellerer Vergleich. Das ist der Grund, warum CPython bestimmte Objekte wie kleine Ganzzahlen, einige Zeichenfolgen usw. zwischenspeichert (oder vielleicht wiederverwendet ). Dies sollte jedoch als behandelt werden Implementierungsdetail werden , das sich (auch wenn es unwahrscheinlich ist) jederzeit ohne Vorwarnung ändern kann.

Sie sollten nur verwenden,is wenn Sie:

  • Ich möchte überprüfen, ob zwei Objekte wirklich dasselbe Objekt sind (nicht nur der gleiche "Wert"). Ein Beispiel kann sein, wenn Sie ein Singleton-Objekt als Konstante verwenden.
  • Ich möchte einen Wert mit einer Python- Konstante vergleichen . Die Konstanten in Python sind:

    • None
    • True1
    • False1
    • NotImplemented
    • Ellipsis
    • __debug__
    • Klassen (zum Beispiel int is int oder int is float)
    • In integrierten Modulen oder Modulen von Drittanbietern können zusätzliche Konstanten vorhanden sein. Zum Beispiel np.ma.maskedaus dem NumPy-Modul)

In jedem anderen Fall sollten Sie verwenden== Gleichheit überprüfen.

Kann ich das Verhalten anpassen?

Es gibt einen Aspekt, der ==in den anderen Antworten noch nicht erwähnt wurde: Er ist Teil von Pythons "Datenmodell" . Das heißt, sein Verhalten kann mit der __eq__Methode angepasst werden . Zum Beispiel:

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)))

Dies ist nur ein künstliches Beispiel, um zu veranschaulichen, dass die Methode wirklich heißt:

>>> MyClass(10) == MyClass(10)
__eq__ method called
True

Beachten Sie, dass standardmäßig (wenn keine andere Implementierung von __eq__in der Klasse oder den Oberklassen gefunden werden kann) Folgendes __eq__verwendet wird is:

class AClass(object):
    def __init__(self, value):
        self._value = value

>>> a = AClass(10)
>>> b = AClass(10)
>>> a == b
False
>>> a == a

Es ist also eigentlich wichtig zu implementieren __eq__ wenn Sie "mehr" als nur einen Referenzvergleich für benutzerdefinierte Klassen wünschen!

Auf der anderen Seite können Sie isSchecks nicht anpassen . Es wird immer nur vergleichen wenn Sie die gleiche Referenz haben.

Werden diese Vergleiche immer einen Booleschen Wert zurückgeben?

Da __eq__es erneut implementiert oder überschrieben werden kann, ist es nicht auf return Trueoder beschränkt False. Es könnte alles zurückgeben (aber in den meisten Fällen sollte es einen Booleschen Wert zurückgeben!).

Beispiel: Bei NumPy-Arrays ==wird ein Array zurückgegeben:

>>> import numpy as np
>>> np.arange(10) == 2
array([False, False,  True, False, False, False, False, False, False, False], dtype=bool)

Aber isSchecks werden immer zurückkehren Trueoder False!


1 Wie Aaron Hall in den Kommentaren erwähnte:

Im Allgemeinen sollten Sie keine is Trueoder is FalseÜberprüfungen durchführen, da diese "Überprüfungen" normalerweise in einem Kontext verwendet werden, der die Bedingung implizit in einen Booleschen Wert konvertiert (z. B. in einer ifAnweisung). Also den is TrueVergleich machen und die implizite boolesche Besetzung machen also mehr Arbeit als nur die boolesche Besetzung - und Sie beschränken sich auf Boolesche Werte (was nicht als pythonisch angesehen wird).

Wie PEP8 erwähnt:

Vergleichen Sie keine booleschen Werte mit Trueoder Falsemit ==.

Yes:   if greeting:
No:    if greeting == True:
Worse: if greeting is True:

2
Ich werde Ihrer Behauptung nicht zustimmen müssen, um "Konstanten" mit zu vergleichen is- Namen, die auf Boolesche Werte verweisen, sollten mit einem booleschen Kontext überprüft werden - wie if __debug__:oder if not __debug__:. Sie sollten dies niemals tun if __debug__ is True:oder if __debug__ == True:- außerdem ist eine Konstante lediglich ein konstanter semantischer Wert, kein Singleton. Daher ist die Überprüfung mit isin diesem Fall nicht semantisch korrekt. Ich fordere Sie auf, eine Quelle zu finden, die Ihre Behauptungen stützt - ich glaube nicht, dass Sie eine finden werden.
Aaron Hall

@AaronHall Warum denkst du, dass die Konstanten keine Singletons sind? Beachten Sie, dass nur None, True, Falseund __debug__sind , was Sie nennen würde „constant semantischen Wert“, weil sie nicht neu zugeordnet werden können. Aber alle sind Singletons.
MSeifert

Lesen Sie PEP 8 - Strg-F und suchen Sie nach dem Wort "schlimmer". - Wenn Sie unittesting
Aaron Hall

@AaronHall Unter bestimmten Umständen brauchen Sie das is Trueoder if Falseüberprüfen wirklich (aber ja, diese sind ziemlich selten - aber wenn Sie sie tun, können Sie sie mit verwenden is). Deshalb benutzt sie manchmal sogar CPython (zum Beispiel hier oder hier )
MSeifert

19

Sie sind völlig anders . isprüft auf Objektidentität, ==prüft auf Gleichheit (ein Begriff, der von den Typen der beiden Operanden abhängt).

Es ist nur ein glücklicher Zufall, dass " is" mit kleinen ganzen Zahlen (z. B. 5 == 4 + 1) richtig zu funktionieren scheint. Dies liegt daran, dass CPython die Speicherung von Ganzzahlen im Bereich (-5 bis 256) optimiert, indem sie zu Singletons gemacht werden . Dieses Verhalten ist vollständig implementierungsabhängig und kann nicht garantiert werden, wenn kleinere transformative Operationen ausgeführt werden.

In Python 3.5 werden beispielsweise auch Singletons für kurze Zeichenfolgen erstellt, deren Aufteilung jedoch dieses Verhalten stört:

>>> "foo" + "bar" == "foobar"
True
>>> "foo" + "bar" is "foobar"
True
>>> "foo"[:] + "bar" == "foobar"
True
>>> "foo"[:] + "bar" is "foobar"
False


6

Ihre Antwort ist richtig. Der isOperator vergleicht die Identität zweier Objekte. Das== Operator vergleicht die Werte zweier Objekte.

Die Identität eines Objekts ändert sich nach seiner Erstellung nie mehr. Sie können es sich als die Adresse des Objekts im Speicher vorstellen.

Sie können das Vergleichsverhalten von Objektwerten steuern, indem Sie eine __cmp__Methode oder eine umfangreiche Vergleichsmethode wie definieren __eq__.



3

Auf den Punkt gebracht wird isgeprüft, ob zwei Referenzen auf dasselbe Objekt verweisen oder nicht. ==prüft, ob zwei Objekte den gleichen Wert haben oder nicht.

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 

2

Wie John Feminella sagte, werden Sie meistens == und! = Verwenden, weil Ihr Ziel darin besteht, Werte zu vergleichen. Ich möchte nur kategorisieren, was Sie den Rest der Zeit tun würden:

Es gibt nur eine Instanz von NoneType, dh None ist ein Singleton. Folglich foo == Noneund foo is Nonebedeuten das gleiche. Der isTest ist jedoch schneller und es ist die Pythonic-Konvention zu verwendenfoo is None .

Wenn Sie eine Selbstbeobachtung durchführen oder sich mit der Speicherbereinigung beschäftigen oder prüfen, ob Ihr benutzerdefiniertes String-Internierungs-Gadget funktioniert oder ähnliches, dann haben Sie wahrscheinlich einen Anwendungsfall für foois bar.

Richtig und Falsch sind (jetzt) ​​auch Singletons, aber es gibt keinen Anwendungsfall für foo == Trueund keinen Anwendungsfall für foo is True.


2

Die meisten von ihnen haben bereits auf den Punkt geantwortet. Nur als zusätzliche Anmerkung (basierend auf meinem Verständnis und Experimentieren, aber nicht aus einer dokumentierten Quelle), die Aussage

== wenn die Objekte, auf die sich die Variablen beziehen, gleich sind

von oben Antworten sollten als gelesen werden

== wenn die Objekte, auf die sich die Variablen beziehen, gleich sind und Objekte desselben Typs / derselben Klasse gehören

. Ich bin zu diesem Schluss gekommen, basierend auf dem folgenden 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)

Hier sind der Inhalt der Liste und des Tupels gleich, aber der Typ / die Klasse sind unterschiedlich.


2

Python Unterschied zwischen ist und gleich (==)

Der is-Operator mag wie der Gleichheitsoperator erscheinen, aber sie sind nicht gleich.

Das is prüft, ob beide Variablen auf dasselbe Objekt zeigen, während das == -Zeichen prüft, ob die Werte für die beiden Variablen gleich sind.

Wenn also der Operator is True zurückgibt, ist die Gleichheit definitiv True, aber das Gegenteil kann True sein oder auch nicht.

Hier ist ein Beispiel, um die Ähnlichkeit und den Unterschied zu demonstrieren.

>>> 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.

1
Verwenden Sie nur Blockzitate für Text, den Sie aus einer anderen Quelle zitiert haben. An diesem Punkt müssen Sie die Zuordnung angeben (siehe stackoverflow.com/help/referencing ). Wenn dies Ihr eigener Text ist, entfernen Sie bitte die Blockzitate.
Martijn Pieters

1

Da die anderen Personen in diesem Beitrag die Frage ausführlich beantworten, möchte ich hauptsächlich den Vergleich zwischen und für Zeichenfolgen hervorhebenis== , die zu unterschiedlichen Ergebnissen führen können, und die Programmierer auffordern, diese sorgfältig zu verwenden.

Bei String - Vergleich, stellen Sie sicher zu verwenden , ==statt is:

str = 'hello'
if (str is 'hello'):
    print ('str is hello')
if (str == 'hello'):
    print ('str == hello')

Aus:

str is hello
str == hello

Aber im folgende Beispiel ==und isunterschiedliche Ergebnisse erhalten:

str = 'hello sam'
    if (str is 'hello sam'):
        print ('str is hello sam')
    if (str == 'hello sam'):
        print ('str == hello sam')

Aus:

str == hello sam

Fazit:

Verwenden Sie issorgfältig zwischen Strings vergleichen


Warum funktioniert "ist" so für Zeichenfolgen mit Leerzeichen?
Akash Gupta

Gemäß den vorherigen Antworten: Es scheint, dass Python das Caching für kleine Ganzzahlen und Zeichenfolgen durchführt, was bedeutet, dass es in diesem Code-Snapshot dieselbe Objektreferenz für das Auftreten von "Hallo" -Strings verwendet, während das Caching für "Hallo Sam" nicht so durchgeführt wurde, wie es ist relativ größer als 'hallo' (dh es werden verschiedene Referenzen des 'hallo sam'-Strings verwaltet, und deshalb gibt der'
is'
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.