collections.OrderedDict

Both dict and OrderedDict remember insertion order today. What OrderedDict still adds: reordering (move_to_end), removing from the FRONT (popitem(last=False)), and == that fails when the order differs.

collections classPython 3.1+Live demo
Common call
OrderedDict(a=1, b=2)
Returns
OrderedDict({'a': 1, 'b': 2})
Replaces
dict when you need to reorder or evict the oldest key
Watch out
OrderedDict == dict ignores order; OrderedDict == OrderedDict does not
collections.OrderedDict([items])
→ OrderedDict

Demo

Live evaluation
Same keys, different order: which comparisons notice?
Try:
Inputs
xlist[str]keys of a
ylist[str]keys of b
Code
from collections import OrderedDict
a = OrderedDict.fromkeys(['a', 'b'])
b = OrderedDict.fromkeys(['b', 'a'])
(a == b, dict(a) == dict(b), a == dict(b))
Result
(False, True, True)

For swapped keys, two OrderedDicts compare unequal, while the same data as plain dicts — or an OrderedDict against a dict — compares equal. In the LRU tab, re-reading "a" moves it to the end, so when "d" arrives the oldest entry is "b", and "b" is evicted.

Parameters

NameTypeRequiredDescription
itemsmapping | iterable of pairsnoInitial content, like dict(): a mapping, (key, value) pairs or keyword arguments — kept in the order given.

Return value

OrderedDict — A new ordered dictionary; arguments are the same as for dict().

Common patterns

LRU cache
move_to_end on every access, popitem(last=False) to evict.
from collections import OrderedDict
cache = OrderedDict()
def get(key):
    cache.move_to_end(key)
    return cache[key]
Order-sensitive comparison with plain dicts
The docs recipe: compare items and order.
same = p == q and all(k1 == k2 for k1, k2 in zip(p, q))
Pop the oldest key from a plain dict
dict.popitem() always takes the newest; this takes the oldest.
k = next(iter(d))
v = d.pop(k)

Examples

1. Order-sensitive equality
from collections import OrderedDict OrderedDict(a=1, b=2) == OrderedDict(b=2, a=1)
Returns
False
2. Plain dicts ignore order
{'a': 1, 'b': 2} == {'b': 2, 'a': 1}
Returns
True
3. Against a dict, order is ignored
from collections import OrderedDict OrderedDict(a=1, b=2) == {'b': 2, 'a': 1}
Returns
True
4. repr
from collections import OrderedDict OrderedDict([('x', 1), ('y', 2)])
Returns
OrderedDict({'x': 1, 'y': 2})
5. Empty repr
from collections import OrderedDict OrderedDict()
Returns
OrderedDict()
6. It is a dict
from collections import OrderedDict isinstance(OrderedDict(), dict)
Returns
True
7. Reorder a key
from collections import OrderedDict od = OrderedDict.fromkeys('abc') od.move_to_end('a') ''.join(od)
Returns
'bca'

Pitfalls

1. Using OrderedDict just to keep order
Since Python 3.7 a plain dict keeps insertion order. Reach for OrderedDict only for its extra methods or order-sensitive equality.
OrderedDict for order
from collections import OrderedDict
list(OrderedDict([('b', 1), ('a', 2)]))
['b', 'a']
a dict does it
list({'b': 1, 'a': 2})
['b', 'a']
2. Calling move_to_end on a plain dict
Only OrderedDict has it. With a dict, pop and re-insert.
dict.move_to_end
d = {'a': 1, 'b': 2}
d.move_to_end('a')
AttributeError: 'dict' object has no attribute 'move_to_end'
d[k] = d.pop(k)
d = {'a': 1, 'b': 2}
d['a'] = d.pop('a')
list(d)
['b', 'a']

When to use

Use it
  • LRU caches and other "recently used" ordering
  • Queues keyed by name where you pop the oldest entry
  • Comparisons where order is part of the value
Reach for something else
  • Only needing insertion order → dict (smaller and faster)
  • A ready-made LRU cache for a function → functools.lru_cache

Notes

CPython impl
Lib/collections/__init__.py has a pure-Python version, but the C implementation in Objects/odictobject.c is used
vs dict
dict keeps insertion order since 3.7; OrderedDict adds move_to_end, popitem(last=), reversible views since 3.5, and order-sensitive == between OrderedDicts
Versions
Added in 3.1; move_to_end in 3.2 (docs.python.org)

FAQ

Not for keeping order — dict does that. It is still useful for move_to_end(), popitem(last=False), and equality that takes order into account, for example in LRU caches.