This should really not surprise you:
>>> a = [1,2] >>> b = [3,4] >>> a is b False >>> a == b False >>> id(a) == id(b) False
After all, a and b are completely different things. However:
>>> [1,2] is [3,4] False >>> [1,2] == [3,4] False >>> id([1,2]) == id([3,4]) True
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
By pure chance, it will use the exact same place for it as it was using for
id will return the same value. This is just to remind you of a couple of things:
a is bis usually (but not always) the same as
id(a) == id(b)
garbage collection can cause side effects you may not be expecting