Today I learned that Python caches the expression {}
, and replaces it with a new empty dict when it's assigned to a variable:
print id({})
# 40357936
print id({})
# 40357936
x = {}
print id(x)
# 40357936
print id({})
# 40356432
I haven't looked at the source code, but I have an idea as to how this might be implemented. (Maybe when the reference count to the global {}
is incremented, the global {}
gets replaced.)
But consider this bit:
def f(x):
x['a'] = 1
print(id(x), x)
print(id(x))
# 34076544
f({})
# (34076544, {'a': 1})
print(id({}), {})
# (34076544, {})
print(id({}))
# 34076544
f
modifies the global dict without causing it to be replaced, and it prints out the modified dict. But outside of f
, despite the id being the same, the global dict is now empty!
What is happening??
It's not being cached -- if you don't assign the result of {}
anywhere, its reference count is 0 and it's cleaned up right away. It just happened that the next one you allocated reused the memory from the old one. When you assign it to x
you keep it alive, and then the next one has a different address.
In your function example, once f
returns there are no remaining references to your dict, so it gets cleaned up too, and the same thing applies.
Python isn't doing any caching here. There are two possibilities when id()
gives the same return value at different points in a program:
id()
was called on the same object twiceid()
was called on was garbage collected before the second object was created, and the second object was created in the same memory location as the originalIn this case, it was the second one. This means that even though print id({}); print id({})
may print the same value twice, each call is on a distinct object.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With