Is it possible to retrieve items from a Python dictionary in the order that they were inserted?
11 Answers
The standard Python dict does this by default if you're using CPython 3.6+ (or Python 3.7+ for any other implementation of Python).
On older versions of Python you can use collections.OrderedDict.
Use OrderedDict(), available since version 2.7
Just a matter of curiosity:
from collections import OrderedDict
a = {}
b = OrderedDict()
c = OrderedDict()
a['key1'] = 'value1'
a['key2'] = 'value2'
b['key1'] = 'value1'
b['key2'] = 'value2'
c['key2'] = 'value2'
c['key1'] = 'value1'
print a == b # True
print a == c # True
print b == c # False
The other answers are correct; it's not possible, but you could write this yourself. However, in case you're unsure how to actually implement something like this, here's a complete and working implementation that subclasses dict which I've just written and tested. (Note that the order of values passed to the constructor is undefined but will come before values passed later, and you could always just not allow ordered dicts to be initialized with values.)
class ordered_dict(dict):
def __init__(self, *args, **kwargs):
dict.__init__(self, *args, **kwargs)
self._order = self.keys()
def __setitem__(self, key, value):
dict.__setitem__(self, key, value)
if key in self._order:
self._order.remove(key)
self._order.append(key)
def __delitem__(self, key):
dict.__delitem__(self, key)
self._order.remove(key)
def order(self):
return self._order[:]
def ordered_items(self):
return [(key,self[key]) for key in self._order]
od = ordered_dict()
od["hello"] = "world"
od["goodbye"] = "cruel world"
print od.order() # prints ['hello', 'goodbye']
del od["hello"]
od["monty"] = "python"
print od.order() # prints ['goodbye', 'monty']
od["hello"] = "kitty"
print od.order() # prints ['goodbye', 'monty', 'hello']
print od.ordered_items()
# prints [('goodbye','cruel world'), ('monty','python'), ('hello','kitty')]
As of Python 3.7, the standard dict preserves insertion order. From the docs:
Changed in version 3.7: Dictionary order is guaranteed to be insertion order. This behavior was implementation detail of CPython from 3.6.
So, you should be able to iterate over the dictionary normally or use popitem().
Or use any of the implementations for the PEP-372 described here, like the odict module from the pythonutils.
I successfully used the pocoo.org implementation, it is as easy as replacing your
my_dict={}
my_dict["foo"]="bar"
with
my_dict=odict.odict()
my_dict["foo"]="bar"
and require just this file