user5319825
user5319825

Reputation: 543

Why Python allocates new id to list, tuples, dict even though having same values?

x1 = 5
y1 = 5
x2 = 'Hello'
y2 = 'Hello'
x3 = [1,2,3]
y3 = [1,2,3]
print(x1 is y1)
print(x2 is y2)
print(x3 is y3)

Output

True
True
False

Why Python assigns a different id to y3, other than x3?

Here x3 and y3 are lists, but Python does the same with tuples and dictionaries too. I also want to know where else Python has the same behaviour of assigning new id's to variables having the same values and why so?

Upvotes: 2

Views: 146

Answers (2)

user5547025
user5547025

Reputation:

Because otherwise this would happen:

x3 = [1,2,3]
y3 = [1,2,3]

x3[0] = "foo"
x3[0] == y3[0] # Does NOT happen!

In fact,

x3[0] != y3[0]

which is a Good Thing™. If x3 and y3 would be identical, changing one would change the other, too. That's generally not expected.

See also when does Python allocate new memory for identical strings? why the behaviour is different for strings.

Also, use == if you want to compare values.

Upvotes: 5

Sнаđошƒаӽ
Sнаđошƒаӽ

Reputation: 17552

Tichodroma put it very nicely. However if you want to have same id() for lists, dicts, etc (if you want to have different names for the same object perhaps) that have same value, you can do it this way:

>>> x3 = y3 = [1,2,3]
>>> print(x3 is y3)
True

In that case x3 and y3 are referencing the same list object in memory. So, if you change any one of them, the other is going to change.

>>> x3[1] = 10
>>> y3
[1, 10, 3]
>>> x3
[1, 10, 3]

Bonus:

If integer values are same, not always will they have same id. Take a look here.

The current implementation keeps an array of integer objects for all integers between -5 and 256, when you create an int in that range you actually just get back a reference to the existing object.

Test:

>>> n = 256
>>> m = 256
>>> n is m
True
>>> n = 257
>>> m = 257
>>> n is m
False
>>> 

One more interesting test (go figure!):

>>> 2**8 is 2**8
True
>>> 2**9 is 2**9
False

P.S.: I am running python 3.4. And the quotation from docs is for python 2.7 (I didn't find the equivalent for python 3.4). But still I am getting outputs like that in python 3.4 I am running. So the current implementation as said for python 2.7 seems still valid for python 3.4.

Upvotes: 3

Related Questions