I am trying to get a sorted dictionary. But the order of the items between mydict
and orddict
doesn't seem to change.
from collections import OrderedDict
mydict = {'a':1,'b':2,'c':3,'d':4}
orddict = OrderedDict(mydict)
print(mydict,orddict)
# print items in mydict:
print('mydict')
for k,v in mydict.items():
print(k,v)
print('ordereddict')
# print items in ordered dictionary
for k,v in orddict.items():
print(k,v)
# print the dictionary keys
# for key in mydict.keys():
# print(key)
# print the dictionary values
# for value in mydict.values():
# print(value)
An OrderedDict
preserves the order elements were inserted:
>>> od = OrderedDict()
>>> od['c'] = 1
>>> od['b'] = 2
>>> od['a'] = 3
>>> od.items()
[('c', 1), ('b', 2), ('a', 3)]
>>> d = {}
>>> d['c'] = 1
>>> d['b'] = 2
>>> d['a'] = 3
>>> d.items()
[('a', 3), ('c', 1), ('b', 2)]
So an OrderedDict
does not order the elements for you, it preserves the order you give it.
If you want to "sort" a dictionary, you probably want
>>> sorted(d.items())
[('a', 1), ('b', 2), ('c', 3)]
As of Python 3.7, a new improvement is:
the insertion-order preservation nature of dict objects has been declared to be an official part of the Python language spec.
This means there is no real need for OrderedDict
anymore. They are almost the same.
However, some minor details to consider...
But there are differences between Python 3.7+ dict
and OrderedDict
, demonstrated here:
from collections import OrderedDict
d = {'b': 1, 'a': 2}
od = OrderedDict([('b', 1), ('a', 2)])
# they are equal with content and order
assert d == od
assert list(d.items()) == list(od.items())
assert repr(dict(od)) == repr(d)
Obviously, there is a difference between the string representation of the two object, with the dict
object in more natural and compact form.
str(d) # {'b': 1, 'a': 2}
str(od) # OrderedDict([('b', 1), ('a', 2)])
As for different methods between the two, this question can be answered with set theory:
d_set = set(dir(d))
od_set = set(dir(od))
od_set.difference(d_set)
# {'__dict__', '__reversed__', 'move_to_end'}
This means the OrderedDict
has at least two features that dict
does not have built-in, but work-arounds are shown here:
# 1) OrderedDict can be reversed (but then what?)
reversed(od)
# <odict_iterator at 0x7fc03f119888>
reversed(d)
# TypeError: 'dict' object is not reversible
# better way to reverse a dict
dict(reversed(list(d.items()))) # {'a': 2, 'b': 1}
# 2) OrderedDict has 'move_to_end' method
od.move_to_end('b') # now it is: OrderedDict([('a', 2), ('b', 1)])
# dict does not, but similar can be done with
d['b'] = d.pop('b') # now it is: {'a': 2, 'b': 1}
Ordered dictionaries are just like regular dictionaries but they remember the order that items were inserted. When iterating over an ordered dictionary, the items are returned in the order their keys were first added.
So it only sorts by order of adding into the dict
You can build an OrderedDict order by key as follow,
orddict = OrderedDict(sorted(mydict.items(), key = lambda t: t[0]))
or simply as @ShadowRanger mentioned in comment
orddict = OrderedDict(sorted(d.items()))
If you want to order by value,
orddict = OrderedDict(sorted(mydict.items(), key = lambda t: t[1]))
More information in 8.3.5.1. OrderedDict Examples and Recipes
Adding on to the answer by Brian, OrderedDict
is really great. Here's why:
You can use it as simple
dict
object because it supports equality testing with otherMapping
objects like collections.counter.OrderedDict
preserves the insertion order as explained by Brian. In addition to that it has a method popitem which returns (key,value) pairs in LIFO order. So, you can also use it as a mapped 'stack'.
You not only get the full features of a dict
but also, some cool tricks.
From the documentation for OrderedDict
(emphasis mine):
Ordered dictionaries are just like regular dictionaries but have some extra capabilities relating to ordering operations. They have become less important now that the built-in
dict
class gained the ability to remember insertion order (this new behavior became guaranteed in Python 3.7).Some differences from
dict
still remain:
The regular
dict
was designed to be very good at mapping operations. Tracking insertion order was secondary.The
OrderedDict
was designed to be good at reordering operations. Space efficiency, iteration speed, and the performance of update operations were secondary.Algorithmically,
OrderedDict
can handle frequent reordering operations better thandict
. This makes it suitable for tracking recent accesses (for example in an LRU cache).The equality operation for
OrderedDict
checks for matching order.The
popitem
method ofOrderedDict
has a different signature. It accepts an optional argument to specify which item is popped.
OrderedDict
has amove_to_end
method to efficiently reposition an element to an endpoint.Until Python 3.8,
dict
lacked a__reversed__
method.
来源:https://stackoverflow.com/questions/34305003/difference-between-dictionary-and-ordereddict-in-python