53 votes

Deux variables en Python ont le même identifiant, mais pas les listes ni les tuples

Deux variables en Python ont le même id:

a = 10
b = 10
a is b
>>> True

Si je prends deux lists:

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

selon ce lien Senderle répondu que immuables des références à des objets ont le même id et changeante des objets comme des listes ont des identifiants différents.

Alors maintenant, en fonction de sa réponse, les n-uplets qui devrait avoir le même id - sens:

a = (1, 2, 3)
b = (1, 2, 3)
a is b
>>> False

Dans l'idéal, comme les tuples ne sont pas mutables, il devrait revenir True, mais il est de retour False!

Quelle est l'explication?

78voto

Kasramvd Points 32864

Des objets immuables n'ont pas le même id, et comme une mater de fait, ce n'est pas vrai pour n'importe quel type d'objets que vous pouvez définir séparément. Chaque fois que vous définissez un objet en Python, vous allez créer un nouvel objet avec une nouvelle identité.

Mais il existe quelques exceptions pour les petits entiers (entre -5 et 256) et de petites chaînes (internés cordes, avec une longueur spéciale (généralement moins de 20 caractères)) qui sont des singletons et ont même id (en fait un objet avec plusieurs pointeur). Vous pouvez vérifier ce fait comme suit:

>>> 30 is 20 + 10
True
>>> 
>>> 300 is 200 + 100
False
>>> 'aa' * 2 is 'a' * 4
True
>>> 'aa' * 20 is 'a' * 40
False

Et pour un objet personnalisé:

>>> class A:
...    pass
... 
>>> A() is A() # Every time you create an instance you'll have a new instance with new identity
False

Notez également que l' is opérateur de vérifier l'identité de l'objet, non pas la valeur. Si vous voulez vérifier la valeur que vous devez utiliser ==:

>>> 300 == 3*100
True

Et depuis il n'y a aucune règle pour les n-uplets (autres types) si vous définissez les deux même tuples dans n'importe quelle taille ils vont obtenir leur propre id:

>>> a = (1,)
>>> b = (1,)
>>>
>>> a is b
False

Et notez que le fait de singleton entiers et internés de chaînes de caractères est vrai même lorsque vous les définir dans mutable et des objets immuables:

>>> a = (100, 700, 400)
>>>
>>> b = (100, 700, 400)
>>>
>>> a[0] is b[0]
True
>>> a[1] is b[1]
False

23voto

Jim Points 8793

Immuable != même objet.*

Immuable objet est simplement un objet dont l'état ne peut pas être modifié; et c'est tout. Lorsqu'un nouvel objet est créé, une nouvelle adresse qui lui sera assignée. En tant que tel, de vérifier si les adresses sont à égalité avec is sera de retour False.

Le fait qu' 1 is 1 ou "a" is "a" retours True est due à l' entier de la mise en cache et de la chaîne de stage effectuée par Python, donc ne le laissez pas vous confondre; il n'est pas en rapport avec les objets en question mutable/immuables.


*Vide des objets immuables ne font référence au même objet et de leur isness ne renvoie true, c'est une implémentation spéciale de cas spécifiques, si.

18voto

Tonechas Points 6220

Regardez ce code:

>>> a = (1, 2, 3)
>>> b = (1, 2, 3)
>>> c = a
>>> id(a)
178153080L
>>> id(b)
178098040L
>>> id(c)
178153080L

Afin de comprendre pourquoi a is c est évaluée comme True alors qu' a is b rendements en False je vous recommande fortement d'exécuter l'étape-par-étape de l'extrait de code ci-dessus dans la Ligne Python Tutor. La représentation graphique des objets en mémoire va fournir vous avec une connaissance approfondie de ce problème (je suis en joignant une copie d'écran).

enter image description here

0voto

AKSHAY KUMAR Points 3

Découvrez ci-dessous le code.. tupils a et b conservent leurs anciennes références(ID) qui nous ont attribué leurs anciennes valeurs. (MAIS, CE NE SERA PAS LE CAS AVEC LES LISTES QU'ILS SONT MUTABLES)

D'abord a et b ont les mêmes valeurs ( (1,2) ), mais ils ont la différence de l'IDs. Après la modification de leurs valeurs, lorsque nous réaffecter la valeur (1,2) pour a et b, ils sont maintenant en référence à LEURS PROPRES mêmes Identifiants (88264264 et 88283400 respectivement).

>>> a = (1,2)
>>> b = (1,2)
>>> a , b
((1, 2), (1, 2))
>>> id(a)
88264264
>>> id(b)
88283400
>>> a = (3,4)
>>> b = (3,4)
>>> id(a)
88280008
>>> id(b)
88264328
>>> a = (1,2)
>>> b = (1,2)
>>> id(a)
88264264
>>> id(b)
88283400
>>> a , b
((1, 2), (1, 2))
>>> id(a) , id(b)
(88264264, 88283400)
>>> 

**Vérifier le lien Pourquoi ne pas les n-uplets ont le même ID assigné les mêmes valeurs? aussi, après la lecture de ce. Un autre cas a également été discuté ici.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X