Why are there 2 implementations of OrderedDict

Why is there a python implementation of ordered dict as well as a C implementation of it? One is in collections and the other is in odictobject.c.

Which one is being used when I import it?

I don’t know exact reason, but it is something along the lines of some exotic platforms end up using Python version.

Either way, it is very convenient to have complementary Python implementations to see the logic. E.g. Most of functools has both C and Python implementations.

C version gets used.

file:///…/python3.12/collections/init.py:339

try:
    from _collections import OrderedDict
except ImportError:
    # Leave the pure Python version in place.
    pass

99% is that you will be using C implementations of everything if they exist.

2 Likes

All dicts are ordered in modern Python so there’s no reason to import it from anywhere. Those exist for backwards compatibility.

Not completely true, although the fact that dict became ordered has reduced usage of OrderedDict significantly.

OrderedDict is doubly-linked list that has functionality that dict does not, which is mainly what concerns changing order.

However, it is currently fairly limited to move_to_end method.

I have made some suggestions to revive it a bit:

And although everyone seemed to agree that it would make sense, no one took it up. I guess it is just not very commonly needed.

2 Likes

Can also be faster:

5.27 seconds  dict
0.04 seconds  OrderedDict

Code:

from collections import OrderedDict
from time import time

for cls in dict, OrderedDict:
    d = cls.fromkeys(range(100000))
    t = time()
    while d:
        del d[next(iter(d))]
    print(f'{time()-t:.2f} seconds ', cls.__name__)

Attempt This Online!

3 Likes

Also, last time I checked, the equality check between OrderedDicts requires that order be the same in both, whereas dict equality does not.

for cls in dict, OrderedDict:
    d1 = cls.fromkeys("abc")
    d2 = cls.fromkeys("cba")
    print(d1)
    print(d2)
    print(cls, d1==d2)
    
{'a': None, 'b': None, 'c': None}
{'c': None, 'b': None, 'a': None}
<class 'dict'> True

OrderedDict([('a', None), ('b', None), ('c', None)])
OrderedDict([('c', None), ('b', None), ('a', None)])
<class 'collections.OrderedDict'> False
3 Likes