web-dev-qa-db-fra.com

Comparaison de chaînes en Python: est vs ==

J'ai remarqué que le script Python que j'écrivais agissait de manière insolite et l'a tracé vers une boucle infinie, dans laquelle la condition de boucle était while line is not ''. En le parcourant dans le débogueur, il s’est avéré que cette ligne était en fait ''. Quand je l'ai changé en !='' plutôt que is not '', cela a bien fonctionné.

Aussi, est-il généralement préférable d'utiliser simplement '==' par défaut, même en comparant les valeurs int ou booléennes? J'ai toujours aimé utiliser 'is' parce que je le trouve plus esthétique et Pythonic (c'est comme ça que je suis tombé dans ce piège ...), mais je me demande si c'est destiné à être réservé aux personnes ayant le souci de trouver deux objets avec le même identifiant.

510
Coquelicot

Pour tous les objets Python intégrés (comme les chaînes, les listes, les dict, les fonctions, etc.), si x est y, alors x == y est également True.

Pas toujours. NaN est un contre-exemple. Mais généralement, identité (is) implique l'égalité (==). L'inverse n'est pas vrai: deux objets distincts peuvent avoir la même valeur.

Aussi, est-il généralement préférable d'utiliser simplement '==' par défaut, même en comparant les valeurs int ou booléennes?

Vous utilisez == pour comparer les valeurs et is pour comparer les identités.

Lorsque vous comparez les ints (ou les types immuables en général), vous préférez toujours les premiers. Il existe une optimisation qui permet de comparer de petits entiers avec is, mais ne vous fiez pas à elle.

Pour les valeurs booléennes, vous ne devriez pas faire de comparaison du tout. Au lieu de:

if x == True:
    # do something

écrire:

if x:
    # do something

Pour comparer avec None, is None est préférable à == None.

J'ai toujours aimé utiliser 'is' parce que je le trouve plus esthétique et Pythonic (c'est comme ça que je suis tombé dans ce piège ...), mais je me demande si c'est destiné à être réservé aux personnes ayant le souci de trouver deux objets avec le même identifiant.

Oui, c'est exactement ce que c'est.

580
dan04

Je voudrais montrer un petit exemple sur la façon dont is et == sont impliqués dans des types immuables. Essayez ça:

a = 19998989890
b = 19998989889 +1
>>> a is b
False
>>> a == b
True

is compare deux objets en mémoire, == compare leurs valeurs. Par exemple, vous pouvez voir que de petits entiers sont mis en cache par Python:

c = 1
b = 1
>>> b is c
True

Vous devez utiliser == pour comparer les valeurs et is pour comparer les identités. (En outre, d'un point de vue anglais, "equals" est différent de "is".)

251
pygabriel

La logique n'est pas imparfaite. La déclaration

si x est y alors x == y est également vrai

devrait jamais être lu comme signifiant

si x == y alors x est y

C'est une erreur logique de la part du lecteur de supposer que l'inverse d'un énoncé logique est vrai. Voir http://en.wikipedia.org/wiki/Converse_ (logique)

68
xubio

Voir cette question

Votre logique en lecture

Pour tous les objets Python intégrés (chaînes, listes, dict, fonctions, etc.), si x est y, alors x == y est également True.

est légèrement imparfait.

Si is s'applique, alors == sera True, mais cela ne s'appliquera PAS à l'envers. == peut donner la valeur True alors que is donne la valeur False.

26
pycruft