drssdinblck drssdinblck - 1 year ago 67
Python Question

How can OrderedDict know about the element order of an already instantiated dict?

I was playing around with the

OrderedDict
type in Python 3.6 and was surprised by its behaviour. When I create a simple
dict
like this in IPython:

d = dict([('sape', 4139), ('guido', 4127), ('jack', 4098)])


I get:

{'guido': 4127, 'jack': 4098, 'sape': 4139}


as an output, which doesn't preserve the order of elements at instantiation for some reason. Now, when I create an
OrderedDict
from
d
like this:

od = OrderedDict(d)


the output is:

OrderedDict([('sape', 4139), ('guido', 4127), ('jack', 4098)])


Now I ask myself, how can the
OrderedDict
-constructor know about the order of elements at instantiation of
d
? And does it always behave the same, such that I can rely on the order of elements in the
OrderedDict
?

I was already reading the Python docs about dictionaries and
OrderedDict
s but I didn't find an answer to my question.

The output from (
sys.version
):

In[22]: sys.version
Out[22]: '3.6.1 (default, Apr 4 2017, 09:40:21) \n[GCC 4.2.1 Compatible Apple LLVM 8.1.0 (clang-802.0.38)]'

Answer Source

It's obvious that the hook (probs sys.displayhook) that IPython uses to display output is pretty printing things. You can see this if, for example, you grabbed the dictionary repr instead (sending a string to be displayed instead of a dict):

dict(t)
Out[18]: {'guido': 4127, 'jack': 4098, 'sape': 4139}

repr(dict(t))
Out[19]: "{'sape': 4139, 'guido': 4127, 'jack': 4098}"

I'm not sure why IPython does this to be honest, it was quite confusing.

The dict d you've created does maintain insertion order, that's why the OrderedDict is maintaining that same order.

The fact that it does is, of course, an implementation detail. Until that is changed (and it does appear that it will) you should stick to using OrderedDict to retain order.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download