OrderedDict not staying in order

2019-07-17 01:47发布

The idea of this loop was to iterate through a list. If a certain property of an object was not a key of the OrderedDict, it would add it. It is a dictionary of lists of objects

for object in someList:
  if object.DATE not in myOrderedDict:
     myOrderedDict[object.DATE]=[]
  myOrderedDict[object.DATE].append(object)

while it does seem to make the OrderedDict mostly correctly, it ends up out of order when it's printed. Instead of having something like (01/13) (02/13) (03/13) it goes more like (02/13) (03/13) (01/13).
Why does this happen and how can it be fixed?

6条回答
疯言疯语
2楼-- · 2019-07-17 02:20

I have mocked up an example of what I think you are getting at, and the OrderedDict does preserve the order you insert in. This may not be what you would want. In that case you can look at the sorted() solution. This should clarify:

import collections

class ob():
    def __init__(self, d, v):
        self.DATE = d
        self.VALUE = v

orderedDict = collections.OrderedDict()
normalDict = {}

someList = [ob('02/13', 2), ob('03/13',3), ob('04/13', 4) , ob('01/13', 5), ob('02/13', 15)]

for a in someList:
  if a.DATE not in orderedDict:
     orderedDict[a.DATE]=[]
     normalDict[a.DATE]=[]
  orderedDict[a.DATE].append(a)
  normalDict[a.DATE].append(a)

orderedDictSorted = collections.OrderedDict(sorted(orderedDict.items()))

print 'Ordered Dict'
print orderedDict.keys()
print 'Dict'
print normalDict.keys()
print 'Ordered Dict Sorted'
print orderedDictSorted.keys()
查看更多
一纸荒年 Trace。
3楼-- · 2019-07-17 02:20

This functionality has been in ruamel.ordereddict (available from PyPI) for Python 2, since 2007:

from ruamel.ordereddict import sorteddict

(this is a fast C implementation, disclaimer: I am the author of tha t package).

查看更多
老娘就宠你
4楼-- · 2019-07-17 02:25

The pure-Python sortedcontainers module has a SortedDict type that can help you. It maintains the dict keys automatically in sorted order and is well documented and tested. You use it just as you would a dict:

>>> from sortedcontainers import SortedDict
>>> mySortedDict = SortedDict()
>>> for object in someList:
>>>     if object.DATE not in mySortedDict:
>>>         mySortedDict[object.DATE]=[]
>>>     mySortedDict[object.DATE].append(object)
>>> list(mySortedDict.keys())
['(01/13)', '(02/13)', '(03/13)']

The sorted containers module is very fast and has a performance comparison page with benchmarks against alternative implementations.

查看更多
兄弟一词,经得起流年.
5楼-- · 2019-07-17 02:26

OrderedDict remembers insertion order, just use a regular dict and sort it before you print it. You can sort your dict alphabetically like this

sorted(myDict, key=myDict.get)
查看更多
我命由我不由天
6楼-- · 2019-07-17 02:30

It would appear that you expect the items in an OrderedDict to be ordered by key, which is not the case. An OrderedDict is ordered by the order items are added to it. From the PEP 372 FAQ:

Does OrderedDict support alternate sort orders such as alphabetical?

No. Those wanting different sort orders really need to be using another technique. The OrderedDict is all about recording insertion order. If any other order is of interest, then another structure (like an in-memory dbm) is likely a better fit.

查看更多
Emotional °昔
7楼-- · 2019-07-17 02:35

An OrderedDict is a dict that remembers the order that keys were first inserted. So the order of the dict is the order of the key inserted. It will not sorted your dict by the key.

查看更多
登录 后发表回答