why shouldn't I always use this instead of a normal dictionary
In Python 2.7, normal OrderedDict
usage will create reference cycles. So any use of OrderedDict
requires the garbage collector to be enabled in order to free the memory. Yes, the garbage collector is on by default in cPython, but disabling it has its uses.
e.g. With cPython 2.7.14
from __future__ import print_function
import collections
import gc
if __name__ == '__main__':
d = collections.OrderedDict([('key', 'val')])
gc.collect()
del d
gc.set_debug(gc.DEBUG_LEAK)
gc.collect()
for i, obj in enumerate(gc.garbage):
print(i, obj)
outputs
gc: collectable <list 00000000033E7908>
gc: collectable <list 000000000331EC88>
0 [[[...], [...], 'key'], [[...], [...], 'key'], None]
1 [[[...], [...], None], [[...], [...], None], 'key']
Even if you just create an empty OrderedDict
(d = collections.OrderedDict()
) and don't add anything to it, or you explicitly try to clean it up by calling the clear
method (d.clear()
before del d
), you will still get one self-referencing list:
gc: collectable <list 0000000003ABBA08>
0 [[...], [...], None]
This seems to have been the case since this commit removed the __del__
method in order to prevent the potential for OrderedDict
to cause uncollectable cycles, which are arguably worse. As noted in the changelog for that commit:
Issue #9825: removed __del__ from the definition of collections.OrderedDict.
This prevents user-created self-referencing ordered dictionaries from
becoming permanently uncollectable GC garbage. The downside is that
removing __del__ means that the internal doubly-linked list has to wait for
GC collection rather than freeing memory immediately when the refcnt drops
to zero.
Note that in Python 3, the fix for the same issue was made differently and uses weakref proxies to avoid cycles:
Issue #9825: Using __del__ in the definition of collections.OrderedDict made
it possible for the user to create self-referencing ordered dictionaries
which become permanently uncollectable GC garbage. Reinstated the Py3.1
approach of using weakref proxies so that reference cycles never get created
in the first place.
for key in sorted(dictvar): print (key, dictvar[key])
. OrderedDict preserves order of insertion, not order of keys. – PaulMcG