Dans l'exemple, 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?
Projet de loi
12
@Bill: C'est un artefact de la façon dont python gère les ints. Python alloue des objets entiers vers lesquels 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
ted
1
@AndresR Non, c'est faux. 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.
Jochen Ritzel
1
@JochenRitzel Vous avez tout à fait raison, merci pour ce commentaire! Alors, je ne comprends pas ce qui se passe "af" is "af"ou () is ()... pourquoi partagent-ils le même emplacement mémoire?
AndresR
2
@AndreasR Pour les chaînes / nombres littéraux dans le code, le compilateur vérifie qu'elles n'existent qu'une seule fois et les réutilise. Des valeurs spéciales telles que (), None, True, False, etc. sont également définies comme des singletons. Pendant l'exécution, le runtime essaie également de réutiliser de petits nombres et chaînes, mais à la fin, c'est un compromis entre la vitesse et la mémoire et ce qui se passe dépend de la façon dont le runtime Python a été implémenté.
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
La note de @ ted sur l'utilisation de id est tout à fait pertinente ici.
Leo Ufimtsev
2
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.
Réponses:
C'est à cela que
is
sert:x is y
renvoieTrue
six
ety
sont le même objet.la source
x is z
renvoieFalse
. Mais si x et z reçoivent les mêmes valeurs au lieu de listes (par exemplex, z = 13, 13
), alorsx is z
retourneTrue
. Pourquoi donc?x
etz
pointent. É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-à-dire270
. Pour plus d'informations, regardez iciis
vé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' * 10000
est False."af" is "af"
ou() is ()
... pourquoi partagent-ils le même emplacement mémoire?y is x
seraTrue
,y is z
seraFalse
.la source
Alors que les deux solutions correctes
x is z
etid(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'informationsCela 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.
la source
Vous pouvez également utiliser id () pour vérifier à quel objet unique se réfère chaque nom de variable.
la source
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.
la source
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.
la source