Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

pythonic way for FIFO order in Dictionary

I am trying to populate a dictionary in python but I would like to preserve the order of the keys as they get in - exactly FIFO like a list would do it.

For example,

I read a file called animals.txt containing the following information:

animal\tconservation_status\n
dog\tdomesticated\n
tiger\tEN\n
panda\tEN\n

I.e.,

animals = {'dog':'dom','tiger':'EN', 'panda':'EN'}
>>> for el in animals:
...     print el
... 
tiger
dog
panda

And in a FIFO SHOULD have been dog, tiger, panda as they come out...

When I read it into a dictionary the order will not be preserved. I would like the order to be preserved such that when I do a for loop the FIRST IN is the FIRST OUT.

I.e., dog, then tiger, then panda.

Is there a nice way to do this without having to keep an external index or a more complex dictionary structure? Not sure, sorry for my naivity here...

like image 872
Dnaiel Avatar asked Sep 14 '25 11:09

Dnaiel


1 Answers

Yes. You use a collections.OrderedDict instead of a regular dictionary.

>>> d = OrderedDict((x,x) for x in reversed(range(10)) )
>>> d
OrderedDict([(9, 9), (8, 8), (7, 7), (6, 6), (5, 5), (4, 4), (3, 3), (2, 2), (1, 1), (0, 0)])
>>> regular = dict((x,x) for x in reversed(range(10)))
>>> regular
{0: 0, 1: 1, 2: 2, 3: 3, 4: 4, 5: 5, 6: 6, 7: 7, 8: 8, 9: 9}

Notice that the OrderedDict preserves the order whereas the regular dict does not.


>>> OrderedDict([('dog','dom'),('tiger','EN'), ('panda','EN')])
OrderedDict([('dog', 'dom'), ('tiger', 'EN'), ('panda', 'EN')])

Another gotcha is that you need to pass items to the constructor (or .update) in a way that preserves order. In other words, you can't pass keyword args to the constructor and expect order to be preserved:

>>> OrderedDict(dog='dom',tiger='EN',panda='EN')  #doesn't preserve order
OrderedDict([('tiger', 'EN'), ('panda', 'EN'), ('dog', 'dom')])
like image 132
mgilson Avatar answered Sep 17 '25 00:09

mgilson