Python dictionaries (objects of type dict) do not preserve the order of elements; CPython has done so since 3.6, but it is implementation-dependent and indefinite in other implementations; the language specification has preserved the order since 3.7.
OrderedDict is provided in the collections module of the standard library as a dictionary that preserves the order. It is safe to use this one.
Import the collections module. It is included in the standard library and does not need to be installed.
import collections
If you write the following, you can omit the collections. in the following examples.
from collections import OrderedDict
The following is a description of how to use OrderedDict.
- Creating an OrderedDict object
- OrderedDict is a subclass of dict
- Move elements to the beginning or end
- Add a new element at any position.
- Rearrange (reorder) elements
- Sort elements by key or value
Creating an OrderedDict object
The constructor collections.OrderedDict() can be used to create an OrderedDict object.
Create an empty OrderedDict object and add values.
od = collections.OrderedDict()
od['k1'] = 1
od['k2'] = 2
od['k3'] = 3
print(od)
# OrderedDict([('k1', 1), ('k2', 2), ('k3', 3)])
It is also possible to specify arguments to the constructor.
You can use keyword arguments, sequences of key-value pairs (such as tuples (key, value)), and so on. The latter can be a list or a tuple as long as it is a key-value pair.
print(collections.OrderedDict(k1=1, k2=2, k3=3))
print(collections.OrderedDict([('k1', 1), ('k2', 2), ('k3', 3)]))
print(collections.OrderedDict((['k1', 1], ['k2', 2], ['k3', 3])))
# OrderedDict([('k1', 1), ('k2', 2), ('k3', 3)])
# OrderedDict([('k1', 1), ('k2', 2), ('k3', 3)])
# OrderedDict([('k1', 1), ('k2', 2), ('k3', 3)])
Until version 3.5, the order of keyword arguments was not preserved, but since version 3.6, it is now preserved.
Changed in version 3.6: With the acceptance of PEP 468, the order of the OrderedDict constructor and the keyword arguments passed to the update() method is preserved.
collections — Container datatypes — Python 3.10.0 Documentation
Normal dictionaries (dict type objects) can also be passed to the constructor, but in the case of implementations where the dict type does not preserve order, the OrderedDict generated from it will also not preserve order.
print(collections.OrderedDict({'k1': 1, 'k2': 2, 'k3': 3}))
# OrderedDict([('k1', 1), ('k2', 2), ('k3', 3)])
OrderedDict is a subclass of dict
OrderedDict is a subclass of dict.
print(issubclass(collections.OrderedDict, dict))
# True
OrderedDict also has the same methods as dict, and the methods for getting, changing, adding, and removing elements are the same as dict.
print(od['k1'])
# 1
od['k2'] = 200
print(od)
# OrderedDict([('k1', 1), ('k2', 200), ('k3', 3)])
od.update(k4=4, k5=5)
print(od)
# OrderedDict([('k1', 1), ('k2', 200), ('k3', 3), ('k4', 4), ('k5', 5)])
del od['k4'], od['k5']
print(od)
# OrderedDict([('k1', 1), ('k2', 200), ('k3', 3)])
See the following article for details.
- Related Articles:Adding elements to a dictionary and joining dictionaries in Python
Move elements to the beginning or end
You can use OrderedDict's own method move_to_end() to move an element to the beginning or the end.
Specify the key as the first argument. The default is to move to the end, but if the second argument last is false, it will be moved to the beginning.
od.move_to_end('k1')
print(od)
# OrderedDict([('k2', 200), ('k3', 3), ('k1', 1)])
od.move_to_end('k1', False)
print(od)
# OrderedDict([('k1', 1), ('k2', 200), ('k3', 3)])
Add a new element at any position.
It is possible to create a new OrderedDict object with a new element added at an arbitrary position. Specifically, this can be done in the following flow.
- List the view objects that can be obtained with the items() method using list().
- Add a tuple (key, value) of key-value pairs in the list's insert() method
- Create a new object by passing it to the constructor collections.OrderedDict()
l = list(od.items())
print(l)
# [('k1', 1), ('k2', 200), ('k3', 3)]
l.insert(1, ('kx', -1))
print(l)
# [('k1', 1), ('kx', -1), ('k2', 200), ('k3', 3)]
od = collections.OrderedDict(l)
print(od)
# OrderedDict([('k1', 1), ('kx', -1), ('k2', 200), ('k3', 3)])
insert() specifies the position to be inserted as the first argument, and the element to be inserted as the second argument.
In the example, a new object is assigned to the original variable, and no new elements are added to the original object itself.
Rearrange (reorder) elements
Replacing elements is the same process as in the example above.
- List the view objects that can be obtained with the items() method using list().
- Replace elements in a list
- Create a new object by passing it to the constructor collections.OrderedDict()
l = list(od.items())
print(l)
# [('k1', 1), ('kx', -1), ('k2', 200), ('k3', 3)]
l[0], l[2] = l[2], l[0]
print(l)
# [('k2', 200), ('kx', -1), ('k1', 1), ('k3', 3)]
od = collections.OrderedDict(l)
print(od)
# OrderedDict([('k2', 200), ('kx', -1), ('k1', 1), ('k3', 3)])
If you want to specify a key and replace it, use the index() method to get the index (position) from the list of keys as shown below.
l = list(od.items())
k = list(od.keys())
print(k)
# ['k2', 'kx', 'k1', 'k3']
print(k.index('kx'))
# 1
l[k.index('kx')], l[k.index('k3')] = l[k.index('k3')], l[k.index('kx')]
print(l)
# [('k2', 200), ('k3', 3), ('k1', 1), ('kx', -1)]
od = collections.OrderedDict(l)
print(od)
# OrderedDict([('k2', 200), ('k3', 3), ('k1', 1), ('kx', -1)])
Sort elements by key or value
Create a list of tuples (key, value) of sorted key-value pairs based on the view object that can be obtained by the items() method, and pass it to the constructor collections.OrderedDict() to create a new object.
Sorting is performed by specifying an anonymous function (lambda expression) that returns a key or value from a tuple (key, value) as the argument key of the built-in function sorted().
If you want to reverse the order, set the reverse argument of sorted() to true.
print(od)
# OrderedDict([('k2', 200), ('k3', 3), ('k1', 1), ('kx', -1)])
od_sorted_key = collections.OrderedDict(
sorted(od.items(), key=lambda x: x[0])
)
print(od_sorted_key)
# OrderedDict([('k1', 1), ('k2', 200), ('k3', 3), ('kx', -1)])
od_sorted_value = collections.OrderedDict(
sorted(od.items(), key=lambda x: x[1], reverse=True)
)
print(od_sorted_value)
# OrderedDict([('k2', 200), ('k3', 3), ('k1', 1), ('kx', -1)])