2010-11-11 4 views
5

Quelqu'un peut-il m'expliquer cela?tuple vs liste des objets en python

>>> [] is [] 
False 
>>>() is() 
True 
>>> (1,) is (1,) 
False 

Je comprends que je devrais utiliser « == » au lieu de « est » pour comparer les valeurs, je me demande pourquoi il est de cette façon?

Répondre

10

is est basé sur l'identité de l'objet. I.E., sont la gauche et la droite le même objet?

Dans tous ces cas, les objets seraient normalement différents (puisque vous avez six littéraux séparés). Cependant, les tuples vides sont le même objet en raison de l'internalisation dépendante de l'implémentation. Comme vous l'avez noté, vous ne devriez jamais vous fier à ce comportement.

Notez que les objets mutables ne peuvent pas être internés, ce qui signifie que le premier doit être faux.

+2

note, "interner" peut (ne habituellement) applicables aux chaînes, ainsi que tout autre littéral/valeur immuable. Comme elles sont immuables, toute implémentation de Python a la possibilité de faire converger différentes références (pointer vers) vers n'importe quelle instance de l'objet. C'est ce que l'internalisation signifie dans ce contexte. L'internalisation est un détail d'implémentation qui optimise pour les cas d'utilisation courants. En passant, les listes Python sont mutables et ne peuvent donc pas être soumises à un internement. –

+1

Le premier n'est pas une comparaison entre une liste et un tuple, mais entre deux listes. C'est faux parce que ce sont des objets différents (c'est-à-dire, des identifiants différents) qui ont seulement la même valeur (c'est-à-dire que les deux sont des listes vides). – rbp

+0

@rbp, merci, j'ai mal lu la question avant. –

2

penser de cette façon: Dans votre premier cas, pour les objets immuables comme tuples, il est sans danger pour la mise en œuvre de python pour les partager si elles sont identiques:

>>> a =() 
>>> b =() 
>>> a is b 
True 

considèrent maintenant:

>>> a = [] 
>>> b = [] 
>>> a.append("foo") 
>>> print a,b 
['foo'] [] 

Il n'est pas possible que a et b soient le même objet, car la modification de a ne devrait pas modifier b. Dans votre dernier exemple, vous êtes de retour aux tuples immuables. L'implémentation Python est autorisé pour les rendre le même objet, mais ce n'est pas obligatoire, et dans ce cas il ne le fait pas (c'est fondamentalement un compromis espace/temps - si vous avez utilisé beaucoup de (1,) dans votre programme vous pourriez économiser la mémoire s'ils étaient internés, mais cela coûterait le temps d'exécution de déterminer si un tuple donné était un (1,) qui pourrait partager l'objet).

3

Soyez prudent lorsque vous comparez par ID. Si un objet est GC'd l'id peut être réutilisé!

>>> id([])==id([]) 
True 

ou même

>>> id([1,2,3])==id(["A","B","C"]) 
True 
+0

Excellent point! – rbp