id([1][::-1]) ==id([1])
being True
is a quirk of CPython using a free list for list
s being implemented as a stack. The first id([1][::-1])
is completely evaluated, and the list
it produced is freed by the time it finishes. When [1]
allocates space for the new list
, it's given the same memory at the same address, which (in CPython) is equivalent to its id
.
id
s are only guaranteed to be unique for as long as the object exists; since the original list
is gone before you make the new list
, no guarantees are violated by both of them having the same id
s at slightly different points in time.
The order of the test matters because id
itself is pulling from the set of recently freed blocks in the small object allocator. The ordering here is:
- Original
[1]
is allocated at address A
- Result of
[::-1]
is allocated at address B
- Immediately thereafter,
[1]
allocation A is returned to list
's free list
id
returns an int
describing address B
- Result of
[::-1]
, B, is returned to free list (ahead of A)
- Second
[1]
is allocated, getting B, the memory previously used by [::-1]
id
is called, accurately producing the same id
as before (because the new [1]
was given the memory recently freed from the list
[::-1]
produced), because both list
s were using address B
That's actually more complicated than it needs to be; id([1]) == id([1])
would end up with the same result as well (it would just leave one fewer list
s on the list
free list).
When you do it the other way around, this happens:
[1]
is allocated at address A
id
returns a new int
describing address A
[1]
is freed and address A is returned to the pool
- The next
[1]
is allocated, getting A, the same memory as the first [1]
[::-1]
is applied to it, getting a new list
from fresh memory B; [1]
is then thrown away
id
is called on the result of [::-1]
getting an int
describing address B; the id
s for addresses A and B don't match
If you created and stored both list
s, then compared the id
s of the still existing list
s to one another, they would be unique because these memory reuse shenanigans wouldn't be able to occur.