3

Possible Duplicate:
Python: Why is (“hello” is “hello”)?

['hello'] is ['hello']    # gives False

Why? Their ids are different. Why didn't a tuple or a number end up returning False?

Community
  • 1
  • 1

3 Answers3

12

Consider the following (Python 2.7.3, 64bit):

>>> a = "Hello"
>>> b = "Hello"
>>> a is b
True

Python interns the short string 'Hello', storing it only once. This is an implementation detail and is not guaranteed by the language standard. It may fail on longer strings:

>>> a = "this is a long string"
>>> b = "this is a long string"
>>> a is b
False

Now consider this:

>>> a = ["Hello"]
>>> b = ["Hello"]
>>> a is b
False

a and b are two different objects. You can check this with id():

>>> id(a)
33826696L
>>> id(b)
33826952L

This is a Good ThingTM because when you do

>>> a[0] = "Goodbye"
>>> a
['Goodbye']
>>> b
['Hello']

However, if you do

>>> a = ["Hello"]
>>> b = a
>>> a is b
True
>>> a[0] = "Goodbye"
>>> b
['Goodbye']

because a and b are names that refer to the same object (id(a) == id(b)). Finally, to show that even though you get

>>> a = ["Hello"]
>>> b = ["Hello"]
>>> a is b
False

the strings are still interned and stored only once:

>>> id(a[0])
33846096L
>>> id(b[0])
33846096L
Tim Pietzcker
  • 328,213
  • 58
  • 503
  • 561
8

The is operator tests to see whether two object references refer to the same object (it is not an equality operator, but an identity operator). In your example you have created two separate lists, therefore you have two different objects, which is why you see False being returned.

codebox
  • 19,927
  • 9
  • 63
  • 81
  • Excellent. But how do I guarantee the name refers to that same object? In other words, how can I ensure that kind of optimization is on for my object? Why can't Python realize `['hello']` is done twice? – user1730053 Oct 09 '12 at 07:13
  • 2
    Try assigning your lists to variables, that might make things clearer: l=['hello'] l is l will return True, l=['hello'] m=['hello'] l is m will return False – codebox Oct 09 '12 at 07:15
  • If you do `a = ['hello']; b = ['hello']`, `a is b` will be False because it's two different objects. After all, you wouldn't want `a[0] = "Goodbye"` to affect `b`, would you? If you do `a = ['hello']; b = a`, however, `a is b` will be True, and `a[0] = "Goodbye"` will affect `b`, too. – Tim Pietzcker Oct 09 '12 at 07:17
  • @TimPietzcker So is mutable obejct causing Python not to optimize it (as a policy decision)? – user1730053 Oct 09 '12 at 07:19
  • 3
    There is nothing to optimize - you have two different, independent objects. The string `'hello'` *is* optimized by interning, so it's only stored once. But your `is` comparison doesn't compare the strings, it compares the lists! – Tim Pietzcker Oct 09 '12 at 07:20
1

When you create a list using the [] syntax, a new list object is created. Lists are mutable objects and thus, even if two lists happen to contain the same elements, they are not the same objects. You can observe that changing a list by calling one of its modifying methods does in fact not change the ID:

In [1]: a = ["hello"]
In [2]: b = ["hello"]
In [3]: id(a)
Out[3]: 4477468112
In [4]: id(b)
Out[4]: 4477467824
In [5]: a.append("world")
In [6]: id(a)
Out[6]: 4477468112
silvado
  • 17,202
  • 2
  • 30
  • 46
  • `"For immutable objects, for example strings, different variables will in fact refer to the same object"` that's not correct. See Tim Pietzcker's answer on this. – phant0m Oct 09 '12 at 08:19
  • Yes, thanks for the hint. I deleted that part. – silvado Oct 09 '12 at 14:35