59

Two variables in Python have the same id:

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

If I take two lists:

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

according to this link Senderle answered that immutable object references have the same id and mutable objects like lists have different ids.

So now according to his answer, tuples should have the same ids - meaning:

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

Ideally, as tuples are not mutable, it should return True, but it is returning False!

What is the explanation?

Community
  • 1
  • 1
Ram Vallury
  • 617
  • 1
  • 6
  • 7
  • You have to differentiate between variables and objects (lists and tuples) - when you compare two objects like this you compare their memory addresses which differ, despite having same list and tuple elements. – dmitryro Jul 04 '16 at 17:23
  • 15
    I think you have misunderstood the answer you link to. Distinct immutable objects have different ids. But for integers < 256 (on most interpreters) the value are pre-loaded in memory and therefore in your first example a is b – Jacques Gaudin Jul 04 '16 at 17:28
  • Thank you @JacquesGaudin! It makes some understanding for me now. – Ram Vallury Jul 04 '16 at 17:36
  • 1
    Whether or not this kind of optimization is done is **not guaranteed**. You should just stop thinking about this, sometimes `is` will return `True` and other times not. If you want to be sure that it returns `True` simply do: `b = a` or `b = tuple(a)` (the `tuple` call will return a reference to the argument if passed a tuple as parameter). – Bakuriu Jul 05 '16 at 07:28
  • I am reopening this because the dup target did not address the main point of this question, namely, if mutability has an effect on identities. – Dimitris Fasarakis Hilliard Aug 16 '16 at 09:39
  • That isn't what the linked answer says. The linked answer **explicitly says** that it is possible to have two distinct, immutable objects with the same value. It goes on to say that it **does not matter** whether there is one object or two, because problems (due to aliasing) only occur when the object is changed, and immutable objects cannot be changed (that's what "immutable" means). – Karl Knechtel Oct 07 '22 at 21:43

5 Answers5

87

Immutable objects don't have the same id, and as a matter of fact this is not true for any type of objects that you define separately. Generally speaking, every time you define an object in Python, you'll create a new object with a new identity. However, for the sake of optimization (mostly) there are some exceptions for small integers (between -5 and 256) and interned strings, with a special length --usually less than 20 characters--* which are singletons and have the same id (actually one object with multiple pointers). You can check this like following:

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

And for a custom object:

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

Also note that the is operator will check the object's identity, not the value. If you want to check the value you should use ==:

>>> 300 == 3*100
True

And since there is no such optimizational or interning rule for tuples or any mutable type for that matter, if you define two same tuples in any size they'll get their own identities, hence different objects:

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

It's also worth mentioning that rules of "singleton integers" and "interned strings" are true even when they've been defined within an iterator.

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

* A good and detailed article on this: http://guilload.com/python-string-interning/
Stephen C
  • 698,415
  • 94
  • 811
  • 1,216
Mazdak
  • 105,000
  • 18
  • 159
  • 188
  • in the last mentioned example (of tuples): a[1] is b[1] should be True, why it returned False? – Ram Vallury Jul 04 '16 at 17:39
  • 4
    @Ram Why you think it should return True, they are 2 separate objects (integers) but with same value (not id). And note that they are not less than 256. – Mazdak Jul 04 '16 at 17:44
  • 1
    yes, agree. I think only integers < 256 will return ids() true. any integer greater than 256 in python interpreter will have its own id space, values will be same. – Ram Vallury Jul 04 '16 at 17:48
  • 10
    The fact that all small 8 bit numbers refer to the same objects in memory is a CPython implementation detail and should not be relied upon for any reason – cat Jul 05 '16 at 04:57
  • However, one should call this twinton or multiton, not singleton, to differ the two patterns. https://en.wikipedia.org/wiki/Multiton_pattern – Amin Negm-Awad Jul 05 '16 at 06:56
  • 2
    @Ram I believe you are seen the situation from the wrong perspective. You should ask yourself why it is returning `True` for `a[0]` and `b[0]`, not why it returns `False` for `a[1]` and `b[1]`. See [this related answer of mine](http://stackoverflow.com/a/15172182/510937) if you want more details about this. – Bakuriu Jul 05 '16 at 07:31
  • @Kasrâmvd "note that the is operator will check the object's identity" - well, what about this - `exec("class A:\n\tdef foo(): pass\na=A()\nassert id(a.foo) == id(a.foo.__get__(a))\nassert a.foo is not a.foo.__get__(a)")`? – stillanoob Oct 05 '18 at 09:22
  • 1
    @stillanoob Yeah, what about it? :)) Your code is a mess of different namespaces and objects that are created during run time. Please explain what's the exact problem here or as a question about it. – Mazdak Oct 05 '18 at 11:05
  • @Kasrâmvd Sorry for the mess. Let there be class `A` with an instance method `foo`. My question is, if the `is` operator checks identity then why do `A.foo is A.foo` evaluates to `False` when `id(A.foo)` apparently returns the same value every time? – stillanoob Oct 05 '18 at 13:55
  • @stillanoob Because each time that you do `A.foo` You're creating a different object. Read my answer here https://stackoverflow.com/questions/27069448/why-does-the-is-operator-say-these-methods-arent-the-same/27069553#27069553 Also note that don't use interactive shell for your internal tests It may mislead you because it's codes get compiled on each input. – Mazdak Oct 05 '18 at 17:05
25

Immutable != same object.*

An immutable object is simply an object whose state cannot be altered; and that is all. When a new object is created, a new address will be assigned to it. As such, checking if the addresses are equal with is will return False.

The fact that 1 is 1 or "a" is "a" returns True is due to integer caching and string interning performed by Python so do not let it confuse you; it is not related with the objects in question being mutable/immutable.


*Empty immutable objects do refer to the same object and their isness does return true, this is a special implementation specific case, though.

Community
  • 1
  • 1
Dimitris Fasarakis Hilliard
  • 150,925
  • 31
  • 268
  • 253
20

Take a look at this code:

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

In order to figure out why a is c is evaluated as True whereas a is b yields False I strongly recommend you to run step-by-step the snippet above in the Online Python Tutor. The graphical representation of the objects in memory will provide you with a deeper insight into this issue (I'm attaching a screenshot).

enter image description here

Tonechas
  • 13,398
  • 16
  • 46
  • 80
1

According to the documentation, immutables may have same id but it is not guaranteed that they do. Mutables always have different ids.

https://docs.python.org/3/reference/datamodel.html#objects-values-and-types

Types affect almost all aspects of object behavior. Even the importance of object identity is affected in some sense: for immutable types, operations that compute new values may actually return a reference to any existing object with the same type and value, while for mutable objects this is not allowed.

In previous versions of Python, tuples were assigned different IDs. (Pre 3.7)

As of Python 3.7+, two variables with the same tuple assigned may have the same id:

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

Integers above 256 also have different ids:

>>>a = 123
>>>b = 123
>>>a is b
True
>>>
>>>a = 257
>>>b = 257
>>>a is b
False
David Le
  • 11
  • 3
0

Check below code.. tupils a and b are retaining their older references(ID) back when we have assigned their older values back. (BUT, THIS WILL NOT BE THE CASE WITH LISTS AS THEY ARE MUTABLE)

Initially a and b have same values ( (1,2) ), but they have difference IDs. After alteration to their values, when we reassign value (1,2) to a and b, they are now referencing to THEIR OWN same IDs (88264264 and 88283400 respectively).

>>> 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)
>>> 

**Check the link Why don't tuples get the same ID when assigned the same values? also after reading this. Another case also been discussed here.

Sateesh
  • 21
  • 7