17

A Python dictionary is stored in no particular order (mappings have no order), e.g.

>>> myDict = {'first':'uno','second':'dos','third':'tres'}
myDict = {'first':'uno','second':'dos','third':'tres'}
>>> myDict
myDict
{'second': 'dos', 'third': 'tres', 'first': 'uno'}

While it is possible to retrieve a sorted list or tuple from a dictionary, I wonder if it is possible to make a dictionary store the items in the order they are passed to it, in the previous example this would mean having the internal ordering as {'first':'uno','second':'dos','third':'tres'} and no different.

I need this because I am using the dictionary to store the values as I read them from a configuration file; once read and processed (the values are altered), they have to be written to a new configuration file in the same order as they were read (this order is not alphabetical nor numerical).

Any thoughts?

Please notice that I am not looking for secondary ways to retrieve the order (like lists), but of ways to make a dictionary be ordered in itself (as it will be in upcoming versions of Python).

double-beep
  • 5,031
  • 17
  • 33
  • 41
Escualo
  • 40,844
  • 23
  • 87
  • 135
  • 2
    http://stackoverflow.com/questions/1867861/python-dictionary-keep-keys-values-in-same-order-as-declared – Ofri Raviv Dec 09 '09 at 08:16
  • @ Ofri Raviv: exact same question. Thanks. – Escualo Dec 09 '09 at 08:24
  • 1
    Since you're trying to maintain order, it's not really a dictionary in the first place. You're doing too many things. You might want both dictionary (for the mapping) and list (to retain the order). Nothing wrong with that. – S.Lott Dec 09 '09 at 11:46
  • @S.Lott: You are right - no need to force a data structure into a different behavior than it was designed for. I will create my own or use the ones already described here. Thanks. – Escualo Dec 09 '09 at 17:15

6 Answers6

34

Try python 2.7 and above, probably 3.1, there is OrderedDict

http://www.python.org/

http://python.org/download/releases/2.7/

>>> from collections import OrderedDict
>>> d = OrderedDict([('first', 1), ('second', 2),
...                  ('third', 3)])
>>> d.items()
[('first', 1), ('second', 2), ('third', 3)]

PEP 372: Adding an ordered dictionary to collections

YOU
  • 120,166
  • 34
  • 186
  • 219
  • Nice. But keep in mind that is a new feature of an upcoming Python release and is not available in older versions. – Andreas Kraft Dec 09 '09 at 08:17
  • ... but I'm stuck with 2.5.1 :( – Escualo Dec 09 '09 at 08:20
  • 3
    Or get the source code of the OrderedDict from this patch: http://bugs.python.org/issue5397 – Georg Schölly Dec 09 '09 at 08:20
  • 2
    If you look at the PEP (http://www.python.org/dev/peps/pep-0372/) you'll find a list of implementations of ordered dictionaries for older pythons. If performance isn't an issue I'd suggest using their own sample implementation of odict (http://dev.pocoo.org/hg/sandbox/raw-file/tip/odict.py), which you'll be able to swap for the standard library one if you ever upgrade. – Michael Dunn Dec 09 '09 at 08:28
  • It's important as well, if its possible to push to an ordered Dict, this is in some applications essential. Otherweise you have to build-up the OrderedDict everytime you have a new element from a dict. – user1767754 Apr 08 '15 at 05:56
  • great, I was looking for this only. Thanks – Kavyajeet Bora Oct 26 '20 at 16:50
4

Use a list to hold the key order

Ofri Raviv
  • 24,375
  • 3
  • 55
  • 55
  • quick and dirty. alas, not very compact (can get brittle). – Daren Thomas Dec 09 '09 at 08:15
  • This works, but I am looking for a more "natural" way, if there is one. It seems that the OrderedDict suggested by S.Mark is the alternative I was looking for. Unfortunately I am stuck with Python 2.5.1 :( – Escualo Dec 09 '09 at 08:19
  • 1
    Not if you encapsulate the dict and list in a single object with dict interface. Which, by the way, is what many Ordered Dict implementations do (don't know about the implementation actually adopted in 2.7) – Vinko Vrsalovic Dec 09 '09 at 08:20
3

Implementations of order-preserving dictionaries certainly do exist.

There is this one in Django, confusingly called SortedDict, that will work in Python >= 2.3 iirc.

Mauve
  • 306
  • 1
  • 2
2

Dictionaries in Python are implemented as hash tables, which is why the order appears random. You could implement your own variation of a dict that sorts, but you'd lose out on the convenient syntax. Instead, keep track of the order of the keys, too.

Initialization:

keys = []
myDict = {}

While reading:

myDict[key] = value
keys.append(key)

While writing:

for key in keys:
  print key, myDict[key]
dmazzoni
  • 12,866
  • 4
  • 38
  • 34
  • My keys are not in alphabetical or numerical order :( They can be anything. – Escualo Dec 09 '09 at 08:11
  • You wouldn't need to lose out on any syntax. Simply implement special methods such as __get__() and __set__() etc so enable use of syntax like dict['key'] and dict['key1'] = newvalue. – Isaac Dec 09 '09 at 08:21
2

Rather Than Explaining The Theoretical Part I'll Give A Simple Example.

>>> from collections import OrderedDict
>>> my_dictionary=OrderedDict()
>>> my_dictionary['foo']=3
>>> my_dictionar['aol']=1
>>> my_dictionary
OrderedDict([('foo', 3), ('aol', 1)])
Mohit Dabas
  • 2,333
  • 1
  • 18
  • 12
-2

There is a very short answer to that.. do this--

dictCopy=yourdictname.copy()

then use the dictCopy , it will be in the same order.