pythondictionaryoverridingbuilt-inordereddictionary

Override the {...} notation so i get an OrderedDict() instead of a dict()?


Update: dicts retaining insertion order is guaranteed for Python 3.7+

I want to use a .py file like a config file. So using the {...} notation I can create a dictionary using strings as keys but the definition order is lost in a standard python dictionary.

My question: is it possible to override the {...} notation so that I get an OrderedDict() instead of a dict()?

I was hoping that simply overriding dict constructor with OrderedDict (dict = OrderedDict) would work, but it doesn't.

Eg:

dict = OrderedDict
dictname = {
   'B key': 'value1',
   'A key': 'value2',
   'C key': 'value3'
   }

print dictname.items()

Output:

[('B key', 'value1'), ('A key', 'value2'), ('C key', 'value3')]

Solution

  • Here's a hack that almost gives you the syntax you want:

    class _OrderedDictMaker(object):
        def __getitem__(self, keys):
            if not isinstance(keys, tuple):
                keys = (keys,)
            assert all(isinstance(key, slice) for key in keys)
    
            return OrderedDict([(k.start, k.stop) for k in keys])
    
    ordereddict = _OrderedDictMaker()
    
    from nastyhacks import ordereddict
    
    menu = ordereddict[
       "about" : "about",
       "login" : "login",
       'signup': "signup"
    ]
    

    Edit: Someone else discovered this independently, and has published the odictliteral package on PyPI that provides a slightly more thorough implementation - use that package instead