Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Two variables in Python have same id, but not lists or tuples

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?

like image 490
Ram Vallury Avatar asked Jul 04 '16 17:07

Ram Vallury


People also ask

Can two variables have same id in Python?

Bookmark this question. Show activity on this post. according to this link Senderle answered that immutable object references have the same id and mutable objects like lists have different ids.

Why id is different in Python?

Example 1: Python id() Since both values are the same, the id is also the same. Note: Since ID is an assigned memory address, it can be different in different systems. So, the output on your system can be different.

What is id python?

Python id() function returns an identity of an object. This is an integer which is guaranteed to be unique. This function takes an argument an object and returns a unique integer number which represents identity. Two objects with non-overlapping lifetimes may have the same id() value.


3 Answers

Immutable objects don't have the same id, and as a mater 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/

like image 111
Mazdak Avatar answered Oct 20 '22 19:10

Mazdak


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.

like image 36
Dimitris Fasarakis Hilliard Avatar answered Oct 20 '22 18:10

Dimitris Fasarakis Hilliard


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

like image 19
Tonechas Avatar answered Oct 20 '22 18:10

Tonechas