Garbage Collection Has Side Effects
Just a quick followup to The problem is is, is it not? This is not mine, I got it from reddit
This should really not surprise you:
After all, a and b are completely different things. However:
Turns out that using literals, one of those things is not like the others.
First, the explanation so you understand why this happens. When you don't have any more references to a piece of data, it will get garbage collected, the memory will be freed, so it can be reused for other things.
In the first case, I am keeping references to both lists in the variables a and b. That means the lists have to exist at all times, since I can always say print a
and python has to know what's in it.
In the second case, I am using literals, which means there is no reference to the lists after they are used. When python evaluates id([1,2]) == id([3,4])
it first evaluates the left side of the ==
. After that is done, there is no need to keep [1,2]
available, so it's deleted. Then, when evaluating the right side, it creates [3,4]
.
By pure chance, it will use the exact same place for it as it was using for [1,2]
. So id
will return the same value. This is just to remind you of a couple of things:
a is b
is usually (but not always) the same asid(a) == id(b)
garbage collection can cause side effects you may not be expecting
Yes, but it's not pure chance - it's the result of object pooling in the implementation. If it were pure chance, the situation you describe would indeed be very rare.
Well, it's pure chance in that, for example, no other thread allocated the memory, and that python uses this specific memory allocation strategy. So, it's not pure chance that it happens this time, but it is pure chance that it happens at all.
It's worthy to note that this behaviour is an implementation detail: it's not enforced by the Python (the language) specification, so in other Python implementations (PyPy, Jython, IronPython) you may get different results.