【问题标题】:Ordered Dictionary is not sorting有序字典未排序
【发布时间】:2014-12-07 12:52:06
【问题描述】:

我一直在网上研究一种创建有序字典的简单方法并登陆 OrderedDict 及其更新方法,我已经成功实现过一次,但是现在代码往往不会对添加的术语进行排序,例如放置的物品是:

      Doc1:  Alpha, zebra, top 
      Doc2:  Andres, tell, exta
      Output: Alpha, top, zebra, Andres, exta, tell
      My goal is to have Alpha, Andres......, top, zebra

这是代码:

    finalindex= collections.OrderedDict()
    ctr=0
    while ctr < docCtr:
        filename = 'dictemp%d.csv' % (ctr,)
        ctr+=1
        dicTempList = io.openTempDic(filename)
        print filename
        for key in dicTempList:
            if key in finalindex:
                print key
                for k, v in finalindex.items():
                newvalue =  v + "," + dicTempList.get(key)
                finalindex.update([(key, newvalue)])
            else:
                finalindex.update([(key, dicTempList.get(key))])
    io.saveTempDic(filename,finalindex)

有人可以帮助我吗?

【问题讨论】:

  • OrderedDict 不是“排序”的字典。它按插入顺序返回键,而不是按字典顺序。你需要像this recipe 这样的东西。
  • 感谢您的快速回复
  • 你可以用有序的字典排序,看我的回答。
  • 如果您无论如何都必须对项目进行排序,那么在您的代码中使用defaultdict 可能会更好

标签: python ordereddictionary


【解决方案1】:

有序字典不是有序字典。

来自文档8.3. collections — High-performance container datatypes

添加了记住 order 条目的 OrderedDict dict 子类

(强调我的)

有序字典是一个哈希表支持的结构,它旁边还维护一个链表,用于存储插入项目的顺序。字典在迭代时使用该链表。

这种类型的结构对于 LRU 缓存非常有用,在这种缓存中,人们只想维护最近请求的 N 个项目,然后在新的缓存超过容量时驱逐最旧的缓存。

代码运行正常。

这背后的设计理念的一些解释可以在Why are there no containers sorted by insertion order in Python's standard libraries? 找到,这表明在选择你想要的容器时,缺少排序结构会混淆“一种明显的方法”(与所有在 Java 中实现 MapSetList 的不同类型的类 - 你使用 LinkedHashMap?还是 ConcurrentSkipListMap?还是 TreeMap?还是 WeakHashMap?)。

【讨论】:

    【解决方案2】:

    OrderedDicts 记住它们被创建的顺序。如果要对其进行排序,则需要在创建它们时进行。以下是对OrderedDictan example taken from the docs 进行排序的方法:

    from collections import OrderedDict
    
    d = {'banana': 3, 'apple':4, 'pear': 1, 'orange': 2}
    sorted_dict = OrderedDict(sorted(d.items(), key=lambda t: t[0]))
    

    这将与另一个有序 dict 一起使用,我更喜欢从中导入模块和引用函数和类,以便读者清楚地了解,所以这是以稍微不同的风格完成的,但同样,为了对其进行排序,你在创建新的OrderedDict之前需要对其进行排序:

    import collections
    ordered_dict=collections.OrderedDict()
    ordered_dict['foo'] = 1
    ordered_dict['bar'] = 2
    ordered_dict['baz'] = 3
    sorted_dict = collections.OrderedDict(sorted(ordered_dict.items(), 
                                                 key=lambda t: t[0]))
    

    并且 sorted_dict 返回:

    OrderedDict([('bar', 2), ('baz', 3), ('foo', 1)])
    

    如果 lambdas 令人困惑,您可以使用 operator.itemgetter

    import operator
    get_first = operator.itemgetter(0)
    sorted_dict = collections.OrderedDict(sorted(ordered_dict.items(), 
                                                 key=get_first))
    

    我正在使用关键参数来演示它们的用法,以防您想按值排序,但 Python 对元组进行排序(dict.items() 提供的通过 Python 2 中的 list 和 Python 中的迭代器进行迭代3) 按第一个元素,然后是第二个元素,依此类推,因此您甚至可以这样做并获得相同的结果:

    sorted_dict = collections.OrderedDict(sorted(ordered_dict.items()))
    

    【讨论】:

    • 您忘记了答案的重要部分,OrderedDict 没有排序,它只保留添加项目的顺序
    • 其实你根本不需要key=。 "get_first" 是 sort 默认执行的操作。
    猜你喜欢
    • 2015-05-06
    • 2017-02-05
    • 2011-09-17
    • 1970-01-01
    • 2011-05-06
    • 2012-06-16
    相关资源
    最近更新 更多