Comment vérifier si deux variables font référence au même objet?
x = ['a', 'b', 'c']
y = x # x and y reference the same object
z = ['a', 'b', 'c'] # x and z reference different objects
Comment vérifier si deux variables font référence au même objet?
x = ['a', 'b', 'c']
y = x # x and y reference the same object
z = ['a', 'b', 'c'] # x and z reference different objects
Réponses:
C'est à cela que issert: x is yrenvoie Truesi xet ysont le même objet.
x is zrenvoie False. Mais si x et z reçoivent les mêmes valeurs au lieu de listes (par exemple x, z = 13, 13), alors x is zretourne True. Pourquoi donc?
xet zpointent. Étant donné que les petits entiers sont communs à l'échec (-1 comme valeur d'erreur, 0 chaque fois que vous indexez quelque chose, les petits nombres sont généralement des valeurs par défaut raisonnables) Python optimise en préallouant de petits nombres (-5 à 256) et réutilise le même objet entier. Ainsi, votre exemple ne fonctionne que pour les nombres de cette plage. Essayez d'attribuer quelque chose de plus grand, c'est-à-dire 270. Pour plus d'informations, regardez ici
isvérifie si deux noms font référence au même emplacement mémoire. Cela n'a rien à voir avec l'objet lui-même. Il est facile d'avoir des objets immuables comme des chaînes qui sont égales mais qui ne sont pas stockées au même emplacement, par exemple ''a'*10000 is 'a' * 10000est False.
"af" is "af"ou () is ()... pourquoi partagent-ils le même emplacement mémoire?
y is xsera True, y is zsera False.
Alors que les deux solutions correctes x is zet id(x) == id(z)ont déjà été publiées, je tiens à souligner un détail de mise en œuvre de python. Python stocke les entiers en tant qu'objets, en tant qu'optimisation, il génère un tas de petits entiers à son début (-5 à 256) et pointe CHAQUE variable contenant un entier avec une petite valeur vers ces objets pré-initialisés. Plus d'informations
Cela signifie que pour les objets entiers initialisés aux mêmes petits nombres (-5 à 256), vérifier si deux objets sont identiques retournera true ( ON C-Pyhon , pour autant que je sache, il s'agit d'un détail d'implémentation ), tandis que pour plus nombres cela ne renvoie vrai que si un objet est initialisé par l'autre.
> i = 13
> j = 13
> i is j
True
> a = 280
> b = 280
> a is b
False
> a = b
> a
280
> a is b
True
Vous pouvez également utiliser id () pour vérifier à quel objet unique se réfère chaque nom de variable.
In [1]: x1, x2 = 'foo', 'foo'
In [2]: x1 == x2
Out[2]: True
In [3]: id(x1), id(x2)
Out[3]: (4509849040, 4509849040)
In [4]: x2 = 'foobar'[0:3]
In [5]: x2
Out[5]: 'foo'
In [6]: x1 == x2
Out[6]: True
In [7]: x1 is x2
Out[7]: False
In [8]: id(x1), id(x2)
Out[8]: (4509849040, 4526514944)
J'aime vraiment avoir un retour visuel, c'est pourquoi j'ouvre parfois simplement http://www.pythontutor.com/visualize.html#mode=edit pour voir comment la mémoire est allouée et ce qui fait référence à quoi.
Ajout de ce gif génial car cette réponse concerne la visualisation.
Ceci est de docs.python.org: "Chaque objet a une identité, un type et une valeur. L'identité d'un objet ne change jamais une fois qu'il a été créé; vous pouvez le considérer comme l'adresse de l'objet en mémoire. L'opérateur 'est' compare l'identité de deux objets; la fonction id () renvoie un entier représentant son identité. "
Apparemment, chaque fois que vous modifiez la valeur, l'objet est recréé comme indiqué par le changement d'identité. La ligne x = 3 suivie de la ligne x = 3,14 ne donne aucune erreur et donne différentes identités, types et valeurs pour x.