Est-il une différence entre `==` et `est` en Python?

Mon Google-fu m'a laissé tomber.

en Python, les deux tests suivants sont-ils équivalents?

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

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

est-ce vrai pour les objets où vous compareriez des instances (un list say)?

D'accord, donc ce genre de réponse à ma question:

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

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

Donc == tests de valeur où is des tests pour voir si elles sont le même objet?

535
demandé sur abccd 2008-09-25 16:27:09

20 réponses

is retournera True si deux variables pointent vers le même objet, == si les objets visés par les variables sont égaux.

>>> a = [1, 2, 3]
>>> b = a
>>> b is a 
True
>>> b == a
True
>>> b = a[:]
>>> b is a
False
>>> b == a
True

dans votre cas, le second test ne fonctionne que parce que Python cache de petits objets entiers, ce qui est un détail d'implémentation. Pour les entiers plus grands, cela ne fonctionne pas:

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

La même chose vaut pour les littéraux de chaîne:

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

S'il vous plaît voir cette question ainsi.

735
répondu Torsten Marek 2017-05-23 11:55:11

il existe une règle empirique simple pour vous dire quand utiliser == ou is .

  • == est pour l'égalité de valeur . L'utiliser quand vous voulez savoir si deux objets ont la même valeur.
  • is signifie égalité de référence . L'utiliser quand vous voulez savoir si deux références se rapportent au même objet.

en général, quand vous comparez quelque chose à un type simple, vous vérifiez habituellement pour l'égalité de valeur , donc vous devez utiliser == . Par exemple, l'intention de votre exemple est probablement de vérifier si x a une valeur égale à 2 ( == ), et non si x se réfère littéralement au même objet que 2.


autre chose à noter: en raison de la façon dont le CPython référence la mise en œuvre fonctionne, vous obtiendrez des résultats inattendus et incohérents si vous utilisez par erreur is pour comparer l'égalité de référence sur des entiers:

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

c'est à peu près ce que nous nous attendions: a et b ont la même valeur, mais sont des entités distinctes. Mais que penser de cela?

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

ceci est incompatible avec le résultat antérieur. Ce qui se passe ici? Il s'avère que l'implémentation de référence de Python cache des objets entiers dans l'intervalle -5..256 comme singleton cas pour des raisons de performances. Voici un exemple démontrant ceci:

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

c'est une autre raison évidente pour ne pas utiliser is : le comportement est laissé à des implémentations quand vous l'utilisez par erreur pour l'égalité des valeurs.

243
répondu John Feminella 2010-01-03 02:09:38

== détermine si les valeurs sont égales, tandis que is détermine si elles sont identiques et égales.

25
répondu stephenbayer 2018-02-18 19:32:12

ils sont complètement différent . is vérifie l'identité de l'objet, tandis que == vérifie l'égalité (une notion qui dépend des types des deux opérandes).

ce n'est qu'une coïncidence heureuse que " is " semble fonctionner correctement avec de petits entiers (par exemple 5 == 4+1). C'est parce que CPython optimise le stockage des entiers dans la gamme (-5 à 256) en leur faisant des singletons . Ce comportement est totalement dépendant de la mise en œuvre et n'est pas garanti d'être préservé sous toutes les formes d'opérations de transformation mineures.

par exemple, Python 3.5 fait aussi des chaînes courtes singletons, mais les trancher perturbe ce comportement:

>>> "foo" + "bar" == "foobar"
True
>>> "foo" + "bar" is "foobar"
True
>>> "foo"[:] + "bar" == "foobar"
True
>>> "foo"[:] + "bar" is "foobar"
False
13
répondu Dan Lenski 2018-07-10 15:14:22

y a-t-il une différence entre == et is en Python?

Oui, ils ont une différence très importante.

== : vérifier l'égalité - la sémantique est que les objets équivalents (qui ne sont pas nécessairement le même objet) seront testés comme égaux. Comme la documentation dit :

le les opérateurs <, >, ==, >=, <=, et != comparer les valeurs de deux objets.

is : vérification d'identité - la sémantique est que l'objet (tel que conservé en mémoire) est l'objet. Encore une fois, la documentation dit :

Les opérateurs is et is not test de l'identité de l'objet: x is y est vrai si et seulement si x et y sont le même objet. L'identité de l'objet est déterminée à l'aide de la fonction id() . x is not y donne l'inverse valeur de vérité.

ainsi, le contrôle d'identité est le même que le contrôle de l'égalité des ID des objets. C'est-à-dire,

a is b

est le même que:

id(a) == id(b)

id est la fonction intégrée qui renvoie un entier qui "est garanti d'être unique parmi les objets simultanément existants" (voir help(id) ) et où a et b sont des objets arbitraires.

Autres Modes D'Emploi

vous devriez utiliser ces comparaisons pour leur sémantique. Utilisez is pour vérifier l'identité et == pour vérifier l'égalité.

PEP 8, le guide officiel de style Python pour la bibliothèque standard mentionne également deux cas d'utilisation pour is :

les comparaisons avec des lettres uniques comme None doivent toujours être faites avec is ou is not , jamais les opérateurs d'égalité.

aussi, méfiez-vous d'écrire if x quand vous voulez vraiment dire if x is not None -- par exemple lors de l'essai d'une variable ou d'un argument par défaut à None a été fixée à une autre valeur. L'autre valeur peut avoir un type (tel que en tant que conteneur) qui pourraient être faux dans un contexte booléen!

Déduire l'égalité de l'identité

si is est vrai, l'égalité peut habituellement être déduite - logiquement, si un objet est lui-même, alors il devrait test comme équivalent à lui-même.

dans la plupart des cas, cette logique est vraie, mais elle repose sur la mise en œuvre de la méthode spéciale __eq__ . Comme le docs dire

le comportement par défaut pour la comparaison d'égalité ( == et != ) est basé sur l'identité des objets. Par conséquent, la comparaison de l'égalité des instances avec la même identité résulte en égalité, et la comparaison de l'égalité des les cas avec des identités différentes entraînent des inégalités. Un la motivation pour ce comportement par défaut est le désir que tous les objets doit être réflexive (i.e. x est y implique x == y).

et dans un souci de cohérence, recommande:

comparaison d'Égalité doit être réflexive. En d'autres termes, identiques les objets doivent comparer égal:

x is y implique x == y

Nous pouvons voir que c'est le comportement par défaut pour les objets personnalisés:

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

le contrapositif est aussi habituellement vrai - si somethings test pas les mêmes, vous pouvez généralement déduire qu'ils ne sont pas le même objet.

puisque les tests d'égalité peuvent être personnalisés, cette inférence n'est pas toujours vraie pour tous les types.

une exception

une exception notable est nan - il teste toujours comme pas égal à lui-même:

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

le contrôle d'identité peut être beaucoup plus rapide que le contrôle d'identité égalité (ce qui pourrait exiger une vérification récursive des membres).

mais il ne peut pas être substitué à l'égalité où vous pouvez trouver plus d'un objet comme équivalent.

notez que la comparaison de l'égalité des listes et des tuples supposera que l'identité des objets est égale (car il s'agit d'un contrôle rapide). Cela peut créer des contradictions si la logique est incohérente - comme c'est le cas pour nan :

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

Un Conte D'Avertissement:

la question tente d'utiliser is pour comparer des entiers. Vous ne devriez pas supposer qu'une instance d'un entier est la même instance que celle obtenue par une autre référence. Cette histoire explique pourquoi.

un commentateur avait du code qui s'appuyait sur le fait que les petits entiers (-5 à 256 inclusivement) sont des singletons en Python, au lieu de vérifier l'égalité.

Wow, cela peut conduire à des bugs insidieux. J'avais un code qui vérifiait si a est b, qui fonctionnait comme je le voulais parce que a et b sont généralement de petits nombres. Le bug n'est arrivé qu'aujourd'hui, après six mois de production, parce que a et b étaient finalement assez grands pour ne pas être mis en cache. - gwg

Il a travaillé dans le développement. Il peut avoir passé quelques unittests.

et il a fonctionné dans la production - jusqu'à ce que le code vérifié pour un entier plus grand que 256, à quel point il a échoué dans la production.

il s'agit d'un échec de production qui aurait pu être détecté lors d'une révision de code ou peut-être avec un vérificateur de style.

permettez-moi de souligner: ne pas utiliser is pour comparer des entiers.

12
répondu Aaron Hall 2018-01-12 20:42:25

https://docs.python.org/library/stdtypes.html#comparisons

is tests d'identité == critères d'égalité

chaque (petite) valeur entière est mappée à une seule valeur, donc chaque 3 est identique et égale. Il s'agit d'un détail de mise en œuvre, ne fait pas partie de la spécification de la langue bien que

9
répondu mmaibaum 2014-11-13 10:02:19

Quelle est la différence entre is et == ?

== et is sont différentes de comparaison! Comme d'autres l'ont déjà dit:

  • == compare les valeurs des objets.
  • is compare les références des objets.

dans les noms de Python se réfèrent à des objets, par exemple dans ce cas value1 et value2 se réfèrent à un int instance de stockage de la valeur 1000 :

value1 = 1000
value2 = value1

enter image description here

parce que value2 fait référence au même objet is et == donnera True :

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

dans l'exemple suivant les noms value1 et value2 se réfèrent à des instances différentes int , même si les deux stockent le même entier:

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

enter image description here

parce que la même valeur (entier) est stockée == sera True , c'est pourquoi il est souvent appelé"comparaison de valeur". Cependant is retournera False parce que ce sont des objets différents:

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

quand utiliser qui?

généralement is est un beaucoup plus rapide comparaison. C'est pourquoi CPython cache (ou peut-être réutilise serait le meilleur terme) Certains objets comme de petits entiers, quelques chaînes, etc. Mais cela devrait être traité comme détail de mise en œuvre qui pourrait (même si peu probable) changer à tout moment sans avertissement.

Vous devriez utiliser uniquement is si vous:

  • je veux vérifier si deux objets sont vraiment le même objet (pas seulement la même "valeur"). Un exemple peut être si vous utilisez un objet singleton comme constante.
  • comparez une valeur à une Python constante . Les constantes en Python sont:

    • None
    • True 1
    • False 1
    • NotImplemented
    • Ellipsis
    • __debug__
    • classes (par exemple int is int ou int is float )
    • il pourrait y avoir des constantes supplémentaires dans les modules intégrés ou les modules tiers. Par exemple np.ma.masked du module NumPy)

In tous les autres cas, vous devez utiliser == pour vérifier l'égalité.

puis-je personnaliser le comportement?

il y a un aspect de == qui n'a pas été mentionné déjà dans les autres réponses: il fait partie de pythons" modèle de données " . Cela signifie que son comportement peut être personnalisé en utilisant la méthode __eq__ . Par exemple:

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

ce n'est qu'un exemple artificiel pour illustrer que la méthode est vraiment appelée:

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

Notez que, par défaut (si aucune autre mise en œuvre de __eq__ peut être trouvé dans la classe ou le super-classes) __eq__ utilise is :

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

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

il est donc en fait important d'implémenter __eq__ si vous voulez" plus " que de la simple comparaison de référence pour des classes personnalisées!

sur le d'autre part vous ne pouvez pas personnaliser is contrôles. Il comparera toujours juste si vous avez la même référence.

est-ce que ces comparaisons retourneront toujours un booléen?

parce que __eq__ peut être ré-implémenté ou annulé, il n'est pas limité à retourner True ou False . Il pourrait retourner n'importe quoi (mais dans la plupart des cas, il devrait retourner un booléen!).

par exemple avec les tableaux NumPy le == retournera un tableau:

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

mais is les chèques retourneront toujours True ou False !


1 comme Aaron Hall l'a mentionné dans les commentaires:

généralement, vous ne devriez pas faire de is True ou is False vérifications parce qu'on utilise normalement ces "vérifications" dans un contexte qui convertit implicitement la condition en booléen (par exemple dans une instruction if ). Ainsi, faire la is True comparaison et la distribution booléenne implicite fait plus de travail que juste faire la distribution booléenne - et vous vous limitez aux booléens (qui n'est pas considéré pythonique).

comme PEP8 mentionne:

ne comparez pas les valeurs booléennes à True ou False par == .

Yes:   if greeting:
No:    if greeting == True:
Worse: if greeting is True:
8
répondu MSeifert 2018-01-20 03:19:40

Votre réponse est correcte. L'opérateur is compare l'identité de deux objets. L'opérateur == compare les valeurs de deux objets.

l'identité d'un objet ne change jamais une fois qu'il a été créé.

vous pouvez contrôler le comportement de comparaison des valeurs d'objet en définissant une méthode __cmp__ ou une riche comparaison méthode comme __eq__ .

6
répondu Dave Webb 2014-11-13 09:24:18

Avoir un coup d'oeil à Débordement de Pile question Python "est" l'opérateur se comporte de manière inattendue avec des entiers .

ce qui se résume le plus souvent à cela " is " vérifie s'ils sont le même objet, pas seulement égaux l'un à l'autre (les nombres en dessous de 256 sont un cas spécial).

4
répondu cobbal 2017-05-23 10:31:38

comme L'a dit John Feminella, la plupart du temps vous utiliserez == et != parce que votre objectif est de comparer les valeurs. Je voudrais juste catégoriser ce que vous feriez le reste du temps:

il y a une et une seule instance de NoneType c'est-à-dire Qu'aucun n'est un singleton. Par conséquent, foo == None et foo is None signifient la même chose. Cependant le test is est plus rapide et la convention pythonique est d'utiliser foo is None .

si vous faites introspection ou de mucking autour de la collecte des ordures ou de vérifier si votre gadget d'entrainement de chaîne sur mesure fonctionne ou semblable, alors vous avez probablement un cas d'utilisation pour foo est bar .

vrai et faux sont aussi (maintenant) singletons, mais il n'y a pas de cas d'utilisation pour foo == True et aucun cas d'utilisation pour foo is True .

2
répondu John Machin 2009-07-06 08:50:52

en Fait, je voulais ajouter un commentaire, mais ne pouvait pas embellir facilement, d'où l'ajout d'une réponse, s'il vous plaît ne considérez pas cela comme une réponse.

C'est ce que j'ai fait pour comprendre --

exécuter suivants un par un et de comprendre de sortie sur chaque étape

a = [1,2]
b = [1,2,3]
b.pop()
id(a)
id(b)
a is b
a == b
1
répondu Pranav 2016-05-11 07:12:33

la plupart d'entre eux ont déjà répondu au point. Tout comme une note supplémentaire (basée sur ma compréhension et l'expérimentation, mais pas à partir d'une source documentée), la déclaration

= = si les objets auxquels se réfèrent les variables sont égaux

les réponses ci-dessus doivent être lues comme suit:

= = si les objets auxquels se réfèrent les variables sont égaux et les objets appartenant au même type /classe

. Je suis arrivé à cette conclusion sur la base du test suivant:

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)

ici le contenu de la liste et tuple sont les mêmes mais le type/classe sont différents.

1
répondu Sandeep 2018-03-07 08:05:20

en bref, is vérifie si deux références pointent vers le même objet ou non. == vérifie si deux objets ont la même valeur ou pas.

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 
1
répondu suvojit_007 2018-07-29 20:17:41

l'opérateur == compare les valeurs des opérandes et vérifie l'égalité des valeurs. Tandis que l'opérateur is vérifie si les deux opérandes se réfèrent ou non au même objet.

a = [1,2,3,4]
b = a
print(a == b) # true
print(a is b) # true

mais si nous le faisons

b = a[:] # b now references a copy of a
print(a == b) # true
print(a is b) # false
print(a is not b) # true

en gros, is peut être considéré comme un raccourci pour id(a) == id(b) . Cependant, au-Delà de cela, il y a des bizarreries de l'environnement d'exécution que compliquer les choses. Cordes courtes et les petits entiers retourneront True par rapport à is , en raison de la machine Python essayant d'utiliser moins de mémoire pour les objets identiques.

a = 'python'
b = 'python'

print(a == b) # true
print(a is b) # true
0
répondu iPython 2018-08-06 14:12:19

Python différence entre l'est et du signe égal(==)

l'opérateur is peut sembler identique à l'opérateur d'égalité mais ils ne sont pas les mêmes.

L'est vérifie si les deux variables pointent vers le même objet alors que le signe == vérifie si les valeurs des deux variables sont les mêmes.

Donc, si l'opérateur retourne True alors l'égalité est certainement Vrai, mais le contraire peut ou ne peut pas être Vrai.

voici un exemple pour démontrer la similitude et la différence.

>>> 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.
0
répondu Projesh Bhoumik 2018-08-08 12:30:33

"==" compare les valeurs

" is "compare les objets sous-jacents

# this pgm is to show you the diff b/n == and is

# a==b and a is b

# == compares values
# is compares references i.e compares wether two variables refer to same object(memory)

a=10
b=10
print(a==b) # returns True as a,b have same value 10 
print(a is b)
# returns True,
# we usually falsey assume that a =10 a new object . b=10 a new obj created
# but actually when b=10 ,nothing but b is pointed to 10 until value of a or b is changed from 10 

a=[1]
b=[1]
print(a==b)
#returns True as a,b have a list element 1
print(a is b)
#returns False because here two different objs are created when initiated with lists
-1
répondu 2016-08-19 22:19:54

o1 is o2 = > compare si o1 et o2 indiquent tous deux le même emplacement physique dans la mémoire (en d'autres termes s'ils sont le même objet)

o1 == o2 = > ici, python appelle la méthode __cmp __(o2) de o1, qui idéalement devrait comparer la valeur et retourner vrai ou faux. (En d'autres termes, il compare la valeur)

JAVA Pour les gens:

  • en Java, pour déterminer si deux variables de chaîne font référence à la même emplacement de la mémoire physique en utilisant str1 = = str2 . (appelé objet identité, et il est écrit en Python comme str1 est str2 ).

  • pour comparer les valeurs des chaînes en Java, usestr1.égale (str2) ; dans Python, utiliser str1 = = str2 .

exemple:

class A():
    ...:     def __init__(self,a):
    ...:         self.a = a
    ...:     def __repr__(self):
    ...:         return str(self.a)
    ...:     def __cmp__(self, value):
    ...:         print self.a
    ...:         print value.a
    ...:         return cmp(self.a, value.a)

sortie Python Shell:

o = A (2) o1 = o

o = = o1 Deux Deux Vrai

O est o1 Vrai

s1 = A(2)

O est o1 Faux

-1
répondu Jadav Bheda 2016-10-26 05:56:38

comme les autres personnes dans ce post répondre à la question dans les détails, je souligner principalement la comparaison entre is et == pour les cordes qui peuvent donner des résultats différents et je voudrais exhorter les programmeurs à les utiliser avec soin.

pour la comparaison de chaîne, assurez-vous d'utiliser == au lieu de is :

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

:

str is hello
str == hello

mais dans l'exemple ci-dessous == et is obtiendra des résultats différents:

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

:

str == hello sam

Conclusion:

utiliser is soigneusement comparer entre les cordes

-1
répondu imanzabet 2018-03-26 18:20:53

Oui, il y a une différence entre les deux.

  • '==' : compare object by value.
  • 'dans : compare objet par référence.

    a = [1,2,3]  
    b = a # both pointing to same object (memory location)
    
    a == b:  
    True  
    a in b:   
    True  #because a and b are pointing to same object
    

examinons maintenant ce cas:

a = [1,2,3]
b = list(a)  # creating copy of object a

a == b:  
True  # as values are same
a in b:   
False  # because they are pointing to different object.
-1
répondu Nitish Chauhan 2018-04-19 18:16:56

bien que toutes les réponses qui reposent sur la mise en œuvre de la comparaison des pointeurs d'objection par rapport à la comparaison des valeurs soient probablement correctes, il y a une raison syntaxique plus profonde pour utiliser is pour déterminer si une valeur variable est None (dans la logique booléenne souvent représentée par NULL ).

Dans la base de données relationnelle et d'autres systèmes logiques, NULL implique que la valeur réelle est "inconnu". Ainsi, l'expression logique xx == NULL doit toujours évaluer à NULL lui-même , car il est impossible de savoir si xx , quelle que soit sa valeur, est la même que la valeur inconnue. Dans les langages de programmation qui adhèrent plus strictement aux règles de la logique booléenne, xx == NULL (ou Pythoniquement xx == None ) évalue correctement à NULL , et des moyens alternatifs doivent être fournis pour déterminer si une valeur variable est NULL . Python est une valeur aberrante à cet égard, en raison de la nature unitaire de la référence objet à None . Mais par souci de clarté et d'exactitude logique, l'utilisation de l'opérateur de comparaison Python is me semble beaucoup plus pratique.

-2
répondu Jimbopdx 2015-07-23 06:11:50