Does dictionary's clear() method delete all the item related objects from memory?
Python documentation on dicts states that del d[key]
removes d[key]
from the dictionary while d.clear()
removes every key, so basically their behavior is the same.
On the memory issue, in Python when you "delete" you are basically removing a reference to an object. When an object is not referenced by any variable nor other object or becomes unreachable, it becomes garbage and can be removed from memory. Python has a garbage collector that from time to time it does this job of checking which objects are garbage and releases the memory allocated for them. If the object you are deleting from the dictionary is referenced by other variable then it is still reachable, thus it is not garbage so it won't be deleted. I leave you here some links if you are interested in reading about garbage collection in general and python's garbage collection in particular.
- http://en.wikipedia.org/wiki/Garbage_collection_(computer_science)
- http://www.digi.com/wiki/developer/index.php/Python_Garbage_Collection
- http://www.doughellmann.com/PyMOTW/gc/
- http://docs.python.org/library/gc.html
There is in fact a very small difference between the two. clear()
will free the memory of the hashset used in the dict, while removing the key will not.
a = dict.fromkeys(range(1000))
In [10]: sys.getsizeof(a)
Out[10]: 49432
In [11]: a.clear()
In [12]: sys.getsizeof(a)
Out[12]: 280
In [13]: a = dict.fromkeys(range(1000))
In [14]: for i in range(1000):
....: del a[i]
....:
In [15]: sys.getsizeof(a)
Out[15]: 49432
Does it behave differently than looping through the dict and
del
eting them?
It's worth noting here that any custom class implementing the MutableMapping
abstract base class gets clear()
as a "free" mixin method.
The only methods you need to override in order to instantiate a MutableMapping
subclass are:
__getitem__, __setitem__, __delitem__, __iter__, __len__
Since you can store the data in your mapping class any way you like, the only way clear()
can figure out how to actually clear your data is by using one or more of those five methods. Now, you might have a guess as to which methods clear()
is using, but why guess when we can experiment?
import collections
class MyMap(collections.MutableMapping):
def __init__(self, mydict):
self._top_secret_data = mydict
def __getitem__(self, key):
print 'getitem'
return self._top_secret_data[key]
def __setitem__(self, key, value):
raise Exception('where did you want that?')
def __len__(self):
raise Exception('a gentleman never tells')
def __delitem__(self, key):
print '[shredding intensifies]'
del self._top_secret_data[key]
def __iter__(self):
def keygen():
for key in self._top_secret_data:
print 'faster! faster!'
yield key
return iter(keygen())
Using the class defined above, it's easy to see how clear()
is implemented:
>>> m = MyMap({1:'a', 2:'b', 3:'c'})
>>> m.clear()
faster! faster!
getitem
[shredding intensifies]
faster! faster!
getitem
[shredding intensifies]
faster! faster!
getitem
[shredding intensifies]
>>>
In other words, the clear()
mixin method is basically implemented as for key in self: del self[key]
.
Now, a disclaimer: Built-in types such as dict
are implemented in C, so the dict.clear
method may not be literally identical to for key in mydict: del mydict[key]
. I would expect some optimization behind the scenes, perhaps a completely different strategy - but hopefully this example gives you some idea as to how you might expect a clear()
method to work in Python.