Skip to main content

Ralsina.Me — Roberto Alsina's website

Garbage Collection Has Side Effects

Just a quick fol­lowup to The prob­lem is is, is it not? This is not mine, I got it from red­dit

This should re­al­ly not sur­prise you:

>>> a = [1,2]
>>> b = [3,4]
>>> a is b
False
>>> a == b
False
>>> id(a) == id(b)
False

Af­ter al­l, a and b are com­plete­ly dif­fer­ent things. How­ev­er:

>>> [1,2] is [3,4]
False
>>> [1,2] == [3,4]
False
>>> id([1,2]) == id([3,4])
True

Turns out that us­ing lit­er­al­s, one of those things is not like the oth­er­s.

First, the ex­pla­na­tion so you un­der­stand why this hap­pen­s. When you don't have any more ref­er­ences to a piece of data, it will get garbage col­lect­ed, the mem­o­ry will be freed, so it can be reused for oth­er 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:

  1. a is b is usu­al­ly (but not al­ways) the same as id(a) == id(b)

  2. garbage col­lec­­tion can cause side ef­­fects you may not be ex­pec­t­ing

David / 2012-01-31 22:39:

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.

Roberto Alsina / 2012-01-31 22:47:

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.

Facundo Batista / 2012-02-03 12:34:

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.