In this post, we will see how to resolve Two list copies has same id
Question:
As I know, using “=” for copying objects actually just creates another reference to the same object. So if I do2367729946880 2367729946880 True
, which is fine and obvious.If I make copies of list, they has different ids:
2646790648192 2646790705984 False
.So far so good. Though, if I try creating copies directly in the print, they unexpectedly has the same id:
2209221063040 2209221063040
How does it happen?
I tried a bunch of different stuff, like:
- assigning copies to variables in the same line in case there is some one-line optimization as Python is an interpreted language
2545996280192 2545996337984
- passing copies to the function to avoid using “=”
1518673867136 1518673852736
- passing copies to the function, using *args because as I know, print() gets arguments same way:
1764444352896 1764444338496
(difference in 3rd least valuable digit)None seem to produce same behaviour. Even comparing ids using operator “is” prints False:
False
But using “==” still gives True:
True
Summing up all the text, I wonder about:
- What provokes this kind of behaviour? It doesn’t seem intended. Is it result of some optimization?
- Can it potentially lead to some nasty unexpected bugs? Is there another way to get two copies to have same id?
Best Answer:
id
returns an integer that is unique for the lifetime of the object. Here, that id
got re-used, b ecause the lifetime of the objects did not overlap. In the expression:a.copy()
is evaluated, it creates a new dict, that dict gets passed to id
, id
returns an integer, the dict is no longer referenced, and immediately reclaimed (this is a Cpython implementation detail). Then, a.copy()
is evaluated again, and again, it is passed to id
. It returns the same int
because that is perfectly in-line with the documented function of id
. You can look at the dissasembled bytecode and see how this works exactly:Another way to see similar behavior:
list
objects, but they were able to re-use the id because they have non-overlapping lifetimes.So, this is all working as intended and documented.
If you have better answer, please add a comment about this, thank you!
Source: Stackoverflow.com