Der
is
Operator stimmt nicht mit den Werten der Variablen überein, sondern mit den Instanzen selbst.
Was bedeutet das wirklich?
Ich habe zwei Variablen mit dem Namen deklariert x
und y
in beiden Variablen die gleichen Werte zugewiesen, aber es wird false zurückgegeben, wenn ich den is
Operator verwende.
Ich brauche eine Klarstellung. Hier ist mein Code.
x = [1, 2, 3]
y = [1, 2, 3]
print(x is y) # It prints false!
Antworten:
Sie haben falsch verstanden, was der
is
Bediener testet. Es wird getestet, ob zwei Variablen auf dasselbe Objekt zeigen , nicht ob zwei Variablen denselben Wert haben.Aus der Dokumentation für den
is
Bediener :Verwenden Sie
==
stattdessen den Operator:Dies wird gedruckt
True
.x
undy
sind zwei separate Listen:Wenn Sie die
id()
Funktion verwenden , sehen Sie dasx
undy
haben unterschiedliche Bezeichner:Wenn Sie jedoch zuweisen
y
, zeigenx
beide auf dasselbe Objekt:und
is
zeigt, dass beide das gleiche Objekt sind, gibt es zurückTrue
.Denken Sie daran, dass Namen in Python nur Bezeichnungen sind, die auf Werte verweisen . Sie können mehrere Namen auf dasselbe Objekt verweisen lassen.
is
sagt Ihnen, ob zwei Namen auf ein und dasselbe Objekt verweisen.==
Gibt an, ob sich zwei Namen auf Objekte beziehen, die denselben Wert haben.quelle
A is B
ist das gleiche wieid(A) == id(B)
.id(A)
in einer Variablen und erwarten später, dassvariable == id(B)
er weiterhin funktioniert. WennA
es in der Zwischenzeit gelöscht wurde,B
hätte es denselben Speicherort erhalten können.\n
>>> y = 5\n
>>> x ist y\n
wahr\n
>>> x == y\n
wahr\n
>>>\n
Ein anderes Duplikat fragte, warum zwei gleiche Zeichenfolgen im Allgemeinen nicht identisch sind, was hier nicht wirklich beantwortet wird:
Warum sind sie nicht die gleiche Saite? Besonders angesichts dessen:
Lassen Sie uns den zweiten Teil etwas verschieben. Wie konnte der erste wahr sein?
Der Interpreter müsste über eine "interne Tabelle" verfügen, eine Tabelle, die Zeichenfolgenwerte Zeichenfolgenobjekten zuordnet. Jedes Mal, wenn Sie versuchen, eine neue Zeichenfolge mit dem Inhalt zu erstellen
'abc'
, erhalten Sie dasselbe Objekt zurück. Wikipedia hat eine detailliertere Diskussion darüber, wie Internierung funktioniert.Und Python hat eine String-Internierungstabelle; Sie können Zeichenfolgen mit der
sys.intern
Methode manuell internieren .In der Tat ist Python erlaubt automatisch intern jede unveränderlichen Typen, aber nicht erforderlich , dies zu tun. Unterschiedliche Implementierungen führen zu unterschiedlichen Werten.
CPython (die Implementierung, die Sie verwenden, wenn Sie nicht wissen, welche Implementierung Sie verwenden) automatisiert automatisch kleine Ganzzahlen und einige spezielle Singletons wie
False
, aber keine Zeichenfolgen (oder große Ganzzahlen oder kleine Tupel oder irgendetwas anderes). Sie können dies ziemlich leicht sehen:OK, aber warum waren
z
undw
identisch?Das ist nicht der Interpreter, der automatisch interniert, sondern die Compiler-Faltwerte.
Wenn das gleiche Kompilierung-String zweimal im selben Modul erscheint (was genau das bedeutet , ist schwer zu definieren-es ist nicht das gleiche wie ein Zeichenfolgenliteral, weil
r'abc'
,'abc'
und'a' 'b' 'c'
sind alle verschieden Literale aber die gleiche Zeichenfolge, aber leicht zu verstehen intuitiv) erstellt der Compiler nur eine Instanz der Zeichenfolge mit zwei Referenzen.Der Compiler kann sogar noch weiter gehen: Er
'ab' + 'c'
kann'abc'
vom Optimierer konvertiert werden. In diesem Fall kann er zusammen mit einer'abc'
Konstanten im selben Modul gefaltet werden.Auch dies ist Python erlaubt, muss aber nicht. In diesem Fall faltet CPython jedoch immer kleine Zeichenfolgen (und z. B. auch kleine Tupel). (Obwohl der Statement-by-Statement-Compiler des interaktiven Interpreters nicht die gleiche Optimierung ausführt wie der Compiler für jeweils einzelne Module, werden interaktiv nicht genau die gleichen Ergebnisse angezeigt.)
Was sollten Sie als Programmierer dagegen tun?
Naja nichts. Sie haben fast nie Grund zur Sorge, wenn zwei unveränderliche Werte identisch sind. Wenn Sie wissen möchten, wann Sie
a is b
anstelle von verwenden könnena == b
, stellen Sie die falsche Frage. Nur immer verwenden,a == b
außer in zwei Fällen:x is None
.x
auf die auswirkty
.quelle
w
undz
aufgrund der Compiler-Faltwerte identisch sind, warum funktioniert dies auch in der REPL, selbst wennid()
die Referenzen überprüft werden? Verwenden der REPL auf Python 3.7is
Gibt nur dann true zurück, wenn es sich tatsächlich um dasselbe Objekt handelt. Wenn sie gleich wären, würde sich auch eine Änderung an der einen in der anderen zeigen. Hier ist ein Beispiel für den Unterschied.quelle
Diese Analogie könnte durch eine doppelte Frage ausgelöst werden :
quelle
is
undis not
sind die beiden Identitätsoperatoren in Python.is
Der Operator vergleicht nicht die Werte der Variablen, sondern die Identitäten der Variablen. Bedenken Sie:Das obige Beispiel zeigt Ihnen, dass die Identität (kann auch die Speicheradresse in Cpython sein) für beide
a
undb
(obwohl ihre Werte gleich sind) unterschiedlich ist. Wenn Sie sagen, dassa is b
dies aufgrund der Nichtübereinstimmung der Identitäten beider Operanden falsch ist, ist dies der Grund. Wenn Sie jedoch sagena == b
, wird true zurückgegeben, da die==
Operation nur überprüft, ob beiden Operanden der gleiche Wert zugewiesen wurde.Interessantes Beispiel (für die Extraklasse):
In dem obigen Beispiel, obwohl
a
undb
sind zwei verschiedene Variablen,a is b
zurückgegebenTrue
. Dies liegt daran , die Art dera
heißt ,int
die ein unveränderliches Objekt ist. Python (ich denke, um Speicherplatz zu sparen) hat also dasselbe Objekt zugewiesen,b
als es mit demselben Wert erstellt wurde. In diesem Fall stimmten die Identitäten der Variablen überein unda is b
stellten sich als solche herausTrue
.Dies gilt für alle unveränderlichen Objekte:
Hoffentlich hilft das.
quelle
-5
oder höher als256
in Python ist, ist falsch. Python speichert Zahlen im Bereich [-5, 256] zwischen.x is y
ist dasselbe wie dasid(x) == id(y)
Vergleichen der Identität von Objekten.Wie @ tomasz-kurgan im Kommentar unten ausgeführt hat
is
, verhält sich der Operator bei bestimmten Objekten ungewöhnlich.Z.B
Ref;
https://docs.python.org/2/reference/expressions.html#is-not
https://docs.python.org/2/reference/expressions.html#id24
quelle
Da können Sie hier eine kleine ganze Zahl überprüfen. Zahlen über 257 sind keine kleinen Ints, daher wird sie als anderes Objekt berechnet.
==
In diesem Fall ist es besser, stattdessen zu verwenden .Weitere Informationen finden Sie hier: http://docs.python.org/2/c-api/int.html
quelle
X zeigt auf ein Array, Y zeigt auf ein anderes Array. Diese Arrays sind identisch, aber der
is
Operator betrachtet die Zeiger, die nicht identisch sind.quelle
is
zeigt die Funktionalität des Bedieners dies.id
wenn Sie nicht danach fragen.Es vergleicht die Objektidentität, dh ob sich die Variablen auf dasselbe Objekt im Speicher beziehen. Es ist wie
==
in Java oder C (beim Vergleichen von Zeigern).quelle
Ein einfaches Beispiel mit Früchten
Ausgabe:
Wenn du es versuchst
Die Ausgabe ist unterschiedlich:
Dies liegt daran, dass der Operator == nur den Inhalt der Variablen vergleicht. Um die Identitäten von 2 Variablen zu vergleichen, verwenden Sie das is Operator
So drucken Sie die Identifikationsnummer:
quelle
Der
is
Betreiber ist nichts anderes als eine englische Version von==
. Da die IDs der beiden Listen unterschiedlich sind, ist die Antwort falsch. Du kannst es versuchen:* Weil die IDs beider Listen gleich wären
quelle
is
ist ‚eine englische Version nicht==
‘