Back to Blog
Python

Python Ordered Dictionary: dict vs OrderedDict

python ordered dictionary: Learn how Python dictionaries maintain insertion order, when to use OrderedDict, and how to leverage ordering in your code.

PythonOrderedDictdictionariesinsertion orderdata structurescollections
Illustration of a Python ordered dictionary showing key-value pairs in sequence with an arrow indicating insertion order.

python ordered dictionary requires a clear understanding of the core syntax, runtime behavior, and practical implementation patterns demonstrated in the examples below.

Python dictionaries have preserved insertion order since Python 3.7, but the collections.OrderedDict class still exists for cases where order is the primary concern. Understanding the difference between the built-in dict and OrderedDict helps you choose the right tool when the order of keys matters.

How Python Dictionaries Guarantee Insertion Order

Since Python 3.7, the language specification guarantees that the built-in dict preserves insertion order. This means that iterating over a dictionary yields keys in the order they were added. This behavior was already present in CPython 3.6 as an implementation detail, but it became a language guarantee in 3.7. If you are using Python 3.7 or later, a regular dict is ordered.

d = {} d['first'] = 1 d['second'] = 2 d['third'] = 3 print(list(d.keys())) # ['first', 'second', 'third']

The order is based on the first insertion of each key. Updating an existing key does not change its position. Deleting a key and re-adding it moves the key to the end.

The OrderedDict Class and Its Extra Methods

The collections module provides OrderedDict, a dictionary subclass that has been explicitly ordered since Python 2.7. While a regular dict now also maintains order, OrderedDict offers methods that are not available on dict:

  • move_to_end(key, last=True) moves an existing key to either end of the dictionary.
  • popitem(last=True) removes and returns the last or first inserted item.

These methods are useful when you need to manipulate the order of entries without rebuilding the dictionary.

from collections import OrderedDict od = OrderedDict() od['a'] = 1 od['b'] = 2 od['c'] = 3 od.move_to_end('a') # moves 'a' to the end print(list(od.keys())) # ['b', 'c', 'a'] od.move_to_end('c', last=False) # moves 'c' to the beginning print(list(od.keys())) # ['c', 'b', 'a']

OrderedDict also has a different equality behavior: two OrderedDict objects are equal only if they have the same items in the same order. For regular dict, order does not affect equality.

OrderedDict vs dict: Key Differences

The table below summarizes the main differences between a regular dict and OrderedDict in Python 3.7+:

FeaturedictOrderedDict
Insertion order preservedYes (since 3.7)Yes
move_to_end() methodNoYes
popitem(last) parameterNo (always last)Yes (last or first)
Equality considers orderNoYes
Memory overheadLowerSlightly higher
Use caseGeneral-purpose mappingWhen order manipulation needed

For most applications, a regular dict is sufficient. OrderedDict becomes valuable when you need to reorder entries or when you rely on order-sensitive equality.

Practical Use Cases for OrderedDict

One common use case is implementing an LRU (Least Recently Used) cache. The move_to_end method makes it easy to track access order.

from collections import OrderedDict class LRUCache: def __init__(self, capacity): self.capacity = capacity self.cache = OrderedDict() def get(self, key): if key not in self.cache: return -1 self.cache.move_to_end(key) return self.cache[key] def put(self, key, value): if key in self.cache: self.cache.move_to_end(key) self.cache[key] = value if len(self.cache) > self.capacity: self.cache.popitem(last=False)

Another scenario is when you need to serialize data while preserving the order of keys, such as when generating JSON output where key order is part of the contract. A regular dict also preserves order, but OrderedDict gives you explicit control if you need to move keys around before serialization.

Performance and Memory Considerations

OrderedDict is implemented as a subclass of dict but maintains an additional linked list to track order. This adds a small memory overhead per entry and makes some operations slightly slower than a plain dict. In practice, the difference is negligible for most workloads, but if you are processing millions of entries and order manipulation is not required, a regular dict is more efficient.

The move_to_end operation is O(1) because it only updates pointers in the linked list. popitem is also O(1). In a regular dict, removing the first item would require rebuilding the dictionary if you needed to simulate this behavior, which is O(n). This is why OrderedDict is the right choice when you need frequent reordering.

Reordering Operations and Edge Cases

When you delete a key from an OrderedDict and re-add it, the key moves to the end, just like a regular dict. However, OrderedDict allows you to move keys explicitly, which is not possible with dict. One edge case to be aware of is that move_to_end raises a KeyError if the key does not exist. Also, popitem with last=False removes the first inserted item, which is useful for FIFO-style queues.

od = OrderedDict([('x', 1), ('y', 2)]) od.move_to_end('z') # KeyError: 'z'

When comparing two OrderedDict instances, order matters:

a = OrderedDict([('a', 1), ('b', 2)]) b = OrderedDict([('b', 2), ('a', 1)]) print(a == b) # False

For regular dictionaries, the same comparison would be True because order is not considered.

Compatibility Notes for Older Python Versions

If you are supporting Python versions before 3.7, a regular dict does not guarantee insertion order. In Python 3.5 and earlier, the order is arbitrary and may vary between runs. If your code relies on order, you must use OrderedDict on those versions. The OrderedDict class is available in all Python 2.7 and 3.x versions, so it is a safe fallback.

When writing code that must run on both old and new Python versions, you can use OrderedDict everywhere to avoid version-specific behavior. However, if you only target Python 3.7+, you can use a regular dict and rely on the language guarantee.

python ordered dictionary: Practical Usage and Code Examples | RYUSLOG DEV