J'ai un programme Python où deux variables sont définies sur la valeur 'public'
. Dans une expression conditionnelle, j'ai la comparaison var1 is var2
qui échoue, mais si je la change, var1 == var2
elle revient True
.
Maintenant, si j'ouvre mon interpréteur Python et que je fais la même comparaison "is", cela réussit.
>>> s1 = 'public'
>>> s2 = 'public'
>>> s2 is s1
True
Qu'est-ce que j'oublie ici?
input = raw_input("Decide (y/n): ")
. Dans ce cas, une entrée "y" etif input == 'y':
renverra "True" tandis queif input is 'y':
renverra False.Réponses:
is
est un test d'identité,==
est un test d'égalité. ce qui se passe dans votre code serait émulé dans l'interpréteur comme ceci:donc pas étonnant qu'ils ne soient pas pareils, non?
En d'autres termes:
is
leid(a) == id(b)
la source
==
vs.equals()
en Java. La meilleure partie est que le Python==
n'est pas analogue au Java==
.None
valeur. Il a donc toujours le même identifiant.Les autres réponses ici sont correctes:
is
est utilisée pour la comparaison d' identité , tandis que==
est utilisée pour la comparaison d' égalité . Étant donné que vous vous souciez de l'égalité (les deux chaînes doivent contenir les mêmes caractères), dans ce cas, l'is
opérateur est tout simplement faux et vous devez utiliser à la==
place.La raison pour laquelle cela
is
fonctionne de manière interactive est que (la plupart) des littéraux de chaîne sont internés par défaut. De Wikipédia:Ainsi, lorsque vous avez deux littéraux de chaîne (mots qui sont littéralement tapés dans le code source de votre programme, entourés de guillemets) dans votre programme qui ont la même valeur, le compilateur Python internera automatiquement les chaînes, les rendant toutes les deux stockées en même temps emplacement de la mémoire. (Notez que cela ne se produit pas toujours , et les règles pour quand cela se produit sont assez compliquées, alors ne vous fiez pas à ce comportement dans le code de production!)
Étant donné que dans votre session interactive, les deux chaînes sont réellement stockées dans le même emplacement de mémoire, elles ont la même identité , de sorte que l'
is
opérateur fonctionne comme prévu. Mais si vous construisez une chaîne par une autre méthode (même si cette chaîne contient exactement les mêmes caractères), alors la chaîne peut être égale , mais ce n'est pas la même chaîne - c'est-à-dire qu'elle a une identité différente , car elle est stocké dans un autre endroit en mémoire.la source
==
et enis
fonction du type de vérification que vous souhaitez. Si vous vous souciez de l' égalité des chaînes (c'est-à-dire du même contenu), vous devez toujours utiliser==
. Si vous vous souciez de savoir si deux noms Python font référence à la même instance d'objet, vous devez utiliseris
. Vous pourriez avoir besoinis
si vous écrivez du code qui gère de nombreuses valeurs différentes sans se soucier de leur contenu, ou bien si vous savez qu'il n'y a qu'un seul élément et que vous souhaitez ignorer d'autres objets prétendant être cette chose. Si vous n'êtes pas sûr, choisissez toujours==
.Le
is
mot-clé est un test d'identité d'objet alors qu'il==
s'agit d'une comparaison de valeurs.Si vous utilisez
is
, le résultat sera vrai si et seulement si l'objet est le même objet. Cependant,==
cela sera vrai chaque fois que les valeurs de l'objet seront les mêmes.la source
Une dernière chose à noter, vous pouvez utiliser la
sys.intern
fonction pour vous assurer d'obtenir une référence à la même chaîne:Comme indiqué ci-dessus, vous ne devez pas utiliser
is
pour déterminer l'égalité des chaînes. Mais cela peut être utile de savoir si vous avez une sorte d'exigence étrange à utiliseris
.Notez que la
intern
fonction était auparavant un module intégré sur Python 2 mais a été déplacée vers lesys
module en Python 3.la source
is
est un test d'identité,==
est un test d'égalité. Cela signifie queis
c'est un moyen de vérifier si deux choses sont les mêmes , ou tout simplement équivalentes.Disons que vous avez un
person
objet simple . S'il s'appelle «Jack» et a «23» ans, c'est l'équivalent d'un autre Jack âgé de 23 ans, mais ce n'est pas la même personne.Ils ont le même âge, mais ce n'est pas le même exemple de personne. Une chaîne peut être équivalente à une autre, mais ce n'est pas le même objet.
la source
jack1.age = 99
, cela ne changera pasjack2.age
. C'est parce que ce sont deux instances différentes, doncjack1 is not jack2
. Cependant, ils peuvent s'égaliserjack1 == jack2
si leur nom et leur âge sont identiques. Cela devient plus compliqué pour les chaînes, car les chaînes sont immuables en Python, et Python réutilise souvent la même instance. J'aime cette explication car elle utilise les cas simples (un objet normal) plutôt que les cas spéciaux (chaînes).Ceci est une note secondaire, mais en python idiomatique, vous verrez souvent des choses comme:
Ceci est sûr, car il est garanti qu'il y aura une instance de l'objet nul (c'est-à-dire aucune) .
la source
Si vous n'êtes pas sûr de ce que vous faites, utilisez le '=='. Si vous en avez un peu plus, vous pouvez utiliser «est» pour des objets connus comme «Aucun».
Sinon, vous finirez par vous demander pourquoi les choses ne fonctionnent pas et pourquoi cela se produit:
Je ne sais même pas si certaines choses sont garanties de rester les mêmes entre les différentes versions / implémentations de python.
la source
D'après mon expérience limitée avec python,
is
est utilisé pour comparer deux objets pour voir s'ils sont le même objet par opposition à deux objets différents avec la même valeur.==
est utilisé pour déterminer si les valeurs sont identiques.Voici un bon exemple:
s1
est une chaîne unicode ets2
est une chaîne normale. Ils ne sont pas du même type, mais ont la même valeur.la source
Je pense que cela a à voir avec le fait que, lorsque la comparaison «est» est évaluée à faux, deux objets distincts sont utilisés. S'il vaut true, cela signifie en interne qu'il utilise le même objet exact et n'en crée pas un nouveau, peut-être parce que vous les avez créés dans une fraction de 2 secondes environ et parce qu'il n'y a pas de grand écart de temps entre les deux, il est optimisé et utilise le même objet.
C'est pourquoi vous devez utiliser l'opérateur d'égalité
==
, nonis
, pour comparer la valeur d'un objet chaîne.Dans cet exemple, j'ai créé s2, qui était un objet chaîne différent précédemment égal à "un" mais ce n'est pas le même objet que
s
, car l'interpréteur n'a pas utilisé le même objet que je ne l'ai pas affecté initialement à "un", si je l'avais fait, cela aurait fait d'eux le même objet.la source
.replace()
Cependant, utiliser comme exemple dans ce contexte n'est probablement pas le meilleur, car sa sémantique peut être déroutante.s2 = s2.replace()
sera toujours créer un nouvel objet chaîne, affecter le nouvel objet chaîne às2
, puis disposer de l'objet chaîne quis2
sert à pointer. Donc, même si vous le faisiez,s = s.replace('one', 'one')
vous obtiendrez toujours un nouvel objet chaîne.Je crois que cela est connu sous le nom de chaînes "internées". Python fait cela, Java aussi, ainsi que C et C ++ lors de la compilation en modes optimisés.
Si vous utilisez deux chaînes identiques, au lieu de gaspiller de la mémoire en créant deux objets chaîne, toutes les chaînes internes avec le même contenu pointent vers la même mémoire.
Il en résulte que l'opérateur "is" Python renvoie True car deux chaînes avec le même contenu pointent vers le même objet chaîne. Cela se produira également en Java et en C.
Cependant, cela n'est utile que pour économiser de la mémoire. Vous ne pouvez pas vous y fier pour tester l'égalité des chaînes, car les divers interprètes, compilateurs et moteurs JIT ne peuvent pas toujours le faire.
la source
Je réponds à la question même si la question est trop ancienne car aucune des réponses ci-dessus ne cite la référence de la langue
En fait, l'opérateur is vérifie l'identité et l'opérateur == vérifie l'égalité,
De la référence du langage:
Les types affectent presque tous les aspects du comportement des objets. Même l'importance de l'identité d'objet est affectée dans un certain sens: pour les types immuables, les opérations qui calculent de nouvelles valeurs peuvent en fait renvoyer une référence à tout objet existant avec le même type et la même valeur, tandis que pour les objets mutables, cela n'est pas autorisé . Par exemple, après a = 1; b = 1, a et b peuvent ou non faire référence au même objet avec la valeur un, selon l'implémentation, mais après c = []; d = [], c et d sont garantis pour faire référence à deux listes vides différentes, uniques et nouvellement créées. (Notez que c = d = [] attribue le même objet à la fois à c et à d.)
donc à partir de la déclaration ci-dessus, nous pouvons déduire que les chaînes qui sont un type immuable peuvent échouer lorsqu'elles sont vérifiées avec "est" et peuvent réussir si elles sont vérifiées avec "est"
Il en va de même pour les tuple int, qui sont également des types immuables
la source
L'
==
équivalence de la valeur de test de l'opérateur. L'is
opérateur teste l'identité de l'objet, Python teste si les deux sont vraiment le même objet (c'est-à-dire vivent à la même adresse en mémoire).Dans cet exemple, Python n'a créé qu'un seul objet chaîne, et les deux,
a
et s'yb
réfère. La raison en est que Python met en cache et réutilise en interne certaines chaînes comme optimisation, il n'y a vraiment qu'une chaîne «banane» en mémoire, partagée par a et b; Pour déclencher le comportement normal, vous devez utiliser des chaînes plus longues:Lorsque vous créez deux listes, vous obtenez deux objets:
Dans ce cas, nous dirions que les deux listes sont équivalentes, car elles ont les mêmes éléments, mais pas identiques, car elles ne sont pas le même objet. Si deux objets sont identiques, ils sont également équivalents, mais s'ils sont équivalents, ils ne sont pas nécessairement identiques.
Si
a
fait référence à un objet et que vous l'assignezb = a
, les deux variables font référence au même objet:la source
is
comparera l'emplacement de la mémoire. Il est utilisé pour la comparaison au niveau de l'objet.==
comparera les variables du programme. Il est utilisé pour vérifier à un niveau de valeur.is
vérifie l'équivalence au niveau de l'adresse==
vérifie l'équivalence du niveau de valeurla source
is
est un test d'identité,==
est un test d'égalité (voir la documentation Python ).Dans la plupart des cas, si
a is b
, alorsa == b
. Mais il y a des exceptions, par exemple:Ainsi, vous ne pouvez utiliser que
is
pour les tests d'identité, jamais les tests d'égalité.la source