Warum vergleichen von strings entweder mit '==' oder 'ist' manchmal ein anderes Ergebnis?
Habe ich ein Python-Programm, in dem zwei Variablen werden auf den Wert festgelegt 'public'
. In einem bedingten Ausdruck ich habe den Vergleich var1 is var2
was nicht, aber wenn ich es ändern zu var1 == var2
es gibt True
.
Nun, wenn ich mein Python-interpreter und das gleiche tun "ist" - Vergleich, gelingt es.
>>> s1 = 'public'
>>> s2 = 'public'
>>> s2 is s1
True
Was vermisse ich hier?
- Ich weiß nicht, etwas über Python, aber es ist möglich, dass man den Vergleich von Werten, während der andere Vergleich von Objekten?
- siehe: stackoverflow.com/questions/1392433/...
- Dieses problem tritt auch auf, wenn Sie Lesen eine Konsole zur Eingabe über z.B.:
input = raw_input("Decide (y/n): ")
. In diesem Fall wird eine Eingabe von "y" undif input == 'y':
wird "True" zurückgegeben, währendif input is 'y':
False zurück. - Dieser blog bietet eine weitaus ausführlichere Erklärung als keine Antwort guilload.com/python-string-interning
- Wie @chris-rico erwähnt, habe ich große Erklärung hier stackoverflow.com/q/15541404/1695680
- können Sie erklären, warum speziell in der original-poster Beispiel den operator "is" nicht auf das Skript, sondern den gleichen Betreiber auf der gleichen strings "true" zurückgegeben, die auf den interaktiven Modus? Es ist der gleiche interpreter, so sollten wir erwarten das gleiche Verhalten über Ihr Praktikum, was Sie haben es, ein Skript auszuführen oder ausführen, die im interaktiven Modus, richtig?
- Mögliche Duplikate von gibt es einen Unterschied zwischen `==` und `ist` in Python?
Du musst angemeldet sein, um einen Kommentar abzugeben.
is
ist Identität testen,==
Gleichheit testen. was passiert in deinem code emuliert werden in der interpreter wie diese:so, kein Wunder, Sie sind nicht die gleichen, richtig?
In anderen Worten:
is
ist dieid(a) == id(b)
==
vs.equals()
in Java. Der beste Teil ist, dass die Python -==
ist nicht Analog zu den Java -==
.None
Wert?None
Wert. Also es hat immer die gleiche id.is None
Ausdruck. Lesen Sie auch gestern kommentierte, dass nach oben.a = 'pub'; b = ''.join(a); a == b, a is b
==
beim Vergleich von unveränderlichen Typen (wie int) undis
beim Vergleich von Objekten." Sie fast nie wollenis
für den Vergleich von Benutzer-definierten Objekten. Die richtige Faustregel ist, "Verwenden==
für alles aberNone
undNotImplemented
Vergleiche, bis Sie verstehen, was Sie tun." Der Artikel schlägt fehl, zu vermitteln, dass die Identität Semantik vonint
s sind eine CPython-Implementierung detail, das gilt nur für die kleinen vonint
s, nicht irgendein caching-Mechanismus, um gemeinsameint
s.Anderen Antworten hier sind richtig:
is
ist für Identität Vergleich, während==
ist für Gleichheit Vergleich. Da das, was Sie interessiert, ist die Gleichheit (die beiden Zeichenfolgen enthalten sollte, die gleichen Zeichen), in diesem Fall dieis
Betreiber ist einfach falsch, und Sie sollten mit==
statt.Den Grund
is
arbeitet interaktiv ist, dass (die meisten) string-Literale sind interniert standardmäßig. Aus Wikipedia:So, wenn man zwei string-Literale (Wörter, die wörtlich eingegeben in Ihren Programm-Quellcode, die von Anführungszeichen umgeben) im Programm, die den gleichen Wert haben, der Python compiler automatisch intern die Saiten, so dass Sie sowohl gespeichert, die an der gleichen Speicherstelle. (Beachten Sie, dass dies nicht immer geschehen, und die Regeln, wenn dies geschieht, sind ziemlich unübersichtlich, also bitte nicht auf dieses Verhalten verlassen in der Produktion-code!)
Seit Ihrer interaktiven session sowohl strings sind eigentlich gespeichert auf dem Speicherplatz, haben Sie die gleichen Identität, so die
is
- operator funktioniert wie erwartet. Aber wenn Sie erstellen Sie eine Zeichenfolge durch eine andere Methode (auch wenn dieser string enthält genau den gleichen Zeichen), dann der string kann gleich, aber es ist nicht die gleiche Zeichenfolge - das heißt, es hat eine andere Identität, denn es ist gespeichert in einem anderen Ort im Speicher.==
/!=
wenn die Zeichenfolgen erstellt werden, über verschiedene Methoden?==
undis
basierend auf welche Art von check Sie wollen. Wenn Sie kümmern sich um die Zeichenfolgen, die gleich (das ist, mit dem gleichen Inhalt), dann sollten Sie immer verwenden==
. Wenn Sie sich sorgen darüber, ob zwei beliebige Python-Namen beziehen sich auf das gleiche Objekt-Instanz, die Sie verwenden solltenis
. Sie müssen möglicherweiseis
wenn Sie code schreiben, die verarbeitet viele verschiedene Werte, ohne dass man sich über Ihren Inhalt, oder anders, wenn Sie wissen, es ist nur eine von etwas, und Sie wollen, ignorieren andere Objekte vorgibt zu sein das Ding. Wenn Sie nicht sicher sind, wählte immer==
.==
ersten Prüfungen für die Objekt-Identität und, in Ermangelung, für string-Gleichheit?Den
is
Schlüsselwort ist ein test für die Objekt-Identität, während==
ist-Wert-Vergleich.Wenn Sie
is
, das Ergebnis wird wahr, wenn und nur, wenn das Objekt das gleiche Objekt. Allerdings==
wird es wahr, jeder Zeit die Werte des Objekts sind die gleichen.Eine Letzte Sache zu beachten ist, können Sie die intern-Funktion, um sicherzustellen, dass Sie immer eine Referenz auf das gleiche string:
Wie oben erwähnt, sollten Sie wahrscheinlich nicht tun werden, ist zu bestimmen, Gleichheit auf strings. Aber dies kann hilfreich sein, zu wissen, wenn Sie einige seltsame Anforderung
is
.Beachten Sie, dass die intern-Funktion verschoben habe, wird eine integrierte Funktion in das Modul
sys
für Python 3.is
ist Identität testen,==
Gleichheit testen. Was dies bedeutet ist, dassis
ist ein Weg, um zu überprüfen, ob zwei Dinge sind die gleichen Dinge, oder auch nur gleichwertig.Sagen du hast eine einfache
person
Objekt. Wenn es mit dem Namen 'Jack' und '23' Jahre alt, es ist äquivalent zu einem anderen 23yr alten Jack, aber es ist nicht die gleiche person.Sie sind im gleichen Alter, aber Sie sind nicht die gleiche Instanz von person. Ein string kann als äquivalent zu einem anderen, aber es ist nicht das gleiche Objekt.
Dies ist eine Randnotiz, aber in idiomatic python-Sie werden oft Sachen sehen wie:
Dies ist sicher, weil es ist garantiert eine Instanz des Null-Objekt (d.h., Keine).
Wenn Sie nicht sicher sind, was Sie tun, verwenden Sie die '=='.
Wenn Sie ein wenig mehr wissen über Sie, die Sie verwenden können, 'ist' für bekannte Objekte wie 'None' stellen.
Sonst wirst du am Ende fragt, warum die Dinge nicht funktionieren und warum dies geschieht:
Ich bin mir auch nicht sicher, ob einige Dinge, die sind garantiert gleich bleiben, zwischen verschiedenen python-Versionen/- Implementierungen.
Aus meiner begrenzten Erfahrung mit python,
is
wird zum vergleichen von zwei Objekten zu sehen, wenn Sie das gleiche Objekt als Gegensatz zu zwei verschiedene Objekte mit dem gleichen Wert.==
wird verwendet, um zu bestimmen, wenn die Werte identisch sind.Ist hier ein gutes Beispiel:
s1
ist ein unicode-string, unds2
ist ein normaler string. Sie sind nicht vom gleichen Typ sind, aber den gleichen Wert.Ich denke, es hat mit der Tatsache zu tun, dass, wenn der 'ist' - Vergleich zu false ausgewertet wird, zwei unterschiedliche Objekte benutzt werden. Wenn es zu true ausgewertet wird, bedeutet intern, dass es exakt das gleiche Objekt und nicht eine neue zu erstellen, vielleicht, weil Sie erstellt wurden, in einem Bruchteil von 2 Sekunden oder so und da gibt es nicht eine große zeitliche Lücke dazwischen ist es optimiert und verwendet das gleiche Objekt.
Dies ist, warum Sie sollten die Verwendung der Gleichheits-operator
==
, nichtis
, zu vergleichen Sie den Wert eines string-Objekts.In diesem Beispiel habe ich aus s2, die war ein anderes string-Objekt zuvor gleich 'eins', aber es ist nicht das gleiche Objekt wie
s
, da der interpreter nicht die gleichen Objekt, als ich zunächst nicht zuordnen "ein", wenn ich es gemacht hätte Sie das gleiche Objekt..replace()
als ein Beispiel in diesem Zusammenhang ist wahrscheinlich nicht die beste, obwohl, weil Ihre Semantik kann verwirrend sein.s2 = s2.replace()
wird immer erstellen Sie eine neuen string-Objekt, weisen Sie das neue string-Objekt zus2
, und dann entsorgen Sie das string-Objekt, dasss2
zeigen. Also selbst wenn Sie habens = s.replace('one', 'one')
Sie würde immer noch ein neues string-Objekt.Ich glaube, dies ist bekannt als "interniert" - strings. Python macht dies, so macht Java, und so tun Sie C und C++, beim kompilieren in optimierten Modi.
Wenn du zwei identische Saiten, statt Speicher zu verschwenden, indem zwei string-Objekte, die alle Internierten strings mit dem gleichen Inhalt zeigen Sie auf den gleichen Speicher.
Diese Ergebnisse in den Python-operator "is" True " zurückgeben, weil Sie zwei strings mit dem selben Inhalt verweisen auf das gleiche string-Objekt. Dies wird auch geschehen in Java und in C.
Dies ist nur nützlich für speicherintensive obwohl. Verlassen Sie sich nicht auf den it-test für string-Gleichheit, weil die verschiedenen Interpreter und Compiler und JIT-engines nicht immer tun.
Ich die Beantwortung der Frage, obwohl die Frage ist alt, weil keine Antworten obigen Zitate die Sprache Referenz
Eigentlich der is-operator überprüft die Identität und den == operator prüft auf Gleichheit,
Von Sprache Referenz:
Arten beeinflussen fast alle Aspekte der Objekt-Verhalten. Auch die Bedeutung von Objekt-Identität betroffen ist in gewissem Sinne: für unveränderliche Typen, Operationen das berechnen von neuen Werten darf eigentlich return eine Referenz auf bestehende Objekt mit demselben Typ und Wert, während für veränderliche Objekte, so ist dies nicht erlaubt. E. g., nach a = 1; b = 1, a und b kann oder kann nicht auf das gleiche Objekt beziehen, mit dem Wert eins, je nach Implementierung, aber nach c = []; d = [], c und d sind garantiert, beziehen sich auf zwei unterschiedliche, einzigartige, neu erstellte leere Listen. (Beachten Sie, dass c = d = [] weist das gleiche Objekt an beide c und d.)
also aus obigen Aussage können wir ableiten, dass die Saiten, die eine unveränderliche geben kann fehlschlagen, wenn diese Option markiert mit "ist" und kann überprüft gelingen, wenn geprüft mit "ist"
Gleiches gilt für int,Tupel, die auch unveränderliche Typen
Den
==
operator test Wert Gleichwertigkeit. Dieis
operator-tests-Objekt-Identität, Python testet, ob die beiden wirklich das gleiche Objekt(D. H., Leben an der gleichen Adresse im Speicher).In diesem Beispiel Python nur erstellt ein string-Objekt, und beide
a
undb
bezieht sich auf es. Der Grund dafür ist, dass Python intern zwischengespeichert und wiederverwendet, einige Zeichenfolgen als Optimierung, es ist wirklich nur ein string "Banane" in Erinnerung, gemeinsam von a und b; auslösen das normale Verhalten, müssen Sie mit mehr Saiten:Wenn Sie erstellen zwei Listen, erhalten Sie zwei Objekte:
In diesem Fall würden wir sagen, dass die beiden Listen sind äquivalent, weil Sie die gleichen Elemente, aber nicht identisch, denn Sie sind nicht das gleiche Objekt. Wenn zwei Objekte identisch sind, sind Sie auch gleichwertig, aber wenn Sie gleichwertig sind, sind Sie nicht notwendigerweise identisch.
Wenn
a
bezieht sich auf ein Objekt und weisen Sieb = a
, dann werden beide Variablen auf das gleiche Objekt beziehen:is
ist Identität testen,==
Gleichheit testen (siehe Python-Dokumentation).In den meisten Fällen, wenn
a is b
, danna == b
. Aber es gibt Ausnahmen, zum Beispiel:So, kann man nur
is
für Identitätsprüfungen, nie Gleichheit testet.is
vergleichen Sie die memory location. Es ist für die Objekt-Ebene-Vergleich.==
vergleichen Sie die Variablen im Programm. Es wird verwendet für die überprüfung auf Wert-Ebene.is
überprüft-Adresse-level-äquivalenz==
Prüfungen für den Wert der Gleichwertigkeit