Why does id({}) == id({}) and id([]) == id([]) in CPython?

cpython, identity, python, python-internals

Solution

CPython is garbage collecting objects as soon as they go out of scope, so the second `[]` is created after the first `[]` is collected. So, most of the time it ends up in the same memory location.

This shows what's happening very clearly (the output is likely to be different in other implementations of Python):

class A:
    def __init__(self): print("a")
    def __del__(self): print("b")

# a a b b False
print(A() is A())
# a b a b True
print(id(A()) == id(A()))

Problem

Why does CPython (no clue about other Python implementations) have the following behavior? ``` tuple1 = () tuple2 = () dict1 = {} dict2 = {} list1 = [] list2 = [] # makes sense, tuples are immutable assert(id(tuple1) == id(tuple2)) # also makes sense dicts are mutable assert(id(dict1) != id(dict2)) # lists are mutable too assert(id(list1) != id(list2)) assert(id(()) == id(())) # why no assertion error on this? assert(id({}) == id({})) # or this? assert(id([]) == id([])) ``` I have a few ideas why it may, but can't find a concrete reason why. EDIT To further prove Glenn's and Thomas' point: ``` [1] id([]) 4330909912 [2] x = [] [3] id(x) 4330909912 [4] id([]) 4334243440 ```

Original source