代码之家  ›  专栏  ›  技术社区  ›  click

使用OrderedDict的构造函数初始化Ordered Dict,使其保留初始数据的顺序的正确方法?

  •  140
  • click  · 技术社区  · 10 年前

    初始化有序字典(OD)以保持初始数据的顺序的正确方法是什么?

    from collections import OrderedDict
    
    # Obviously wrong because regular dict loses order
    d = OrderedDict({'b':2, 'a':1}) 
    
    # An OD is represented by a list of tuples, so would this work?
    d = OrderedDict([('b',2), ('a', 1)])
    
    # What about using a list comprehension, will 'd' preserve the order of 'l'
    l = ['b', 'a', 'c', 'aa']
    d = OrderedDict([(i,i) for i in l])
    

    问题:

    • 威尔 OrderedDict 保持初始化时传递的元组列表、元组的元组、列表的元组或列表的列表等的顺序(上面的第二和第三示例)?

    • 如何验证 有序字典 实际维持订单?自 dict 如果我的测试向量幸运地具有与dict的不可预测顺序相同的初始顺序,该怎么办?例如,如果不是 d = OrderedDict({'b':2, 'a':1}) 我在写 d = OrderedDict({'a':1, 'b':2}) ,我可以错误地得出这样的结论:秩序得到了维持。在这种情况下,我发现 字典 按字母顺序排列,但这可能并不总是正确的。使用反例来验证数据结构是否保持顺序,除了重复尝试测试向量直到一个中断,还有什么可靠的方法?

    P.S.我就把这个留在这里 reference :“OrderedDict构造函数和update()方法都接受关键字参数,但它们的顺序丢失了,因为Python函数调用语义使用常规无序字典传入关键字参数”

    P.P.S:希望在将来,OrderedDict也能保持kwargs的顺序(示例1): http://bugs.python.org/issue16991

    3 回复  |  直到 6 年前
        1
  •  105
  •   BrenBarn    10 年前

    OrderedDict将保留它有权访问的任何顺序。将有序数据传递给它以进行初始化的唯一方法是传递键值对列表(或更一般地,可迭代的),如前两个示例所示。正如您链接到的文档所述,当您传入关键字参数或dict参数时,OrderedDict无法访问任何顺序,因为OrderedDict构造函数在看到它之前,其中的任何顺序都会被删除。

    请注意,在上一个示例中使用列表理解不会改变任何内容。两者之间没有区别 OrderedDict([(i,i) for i in l]) OrderedDict([('b', 'b'), ('a', 'a'), ('c', 'c'), ('aa', 'aa')]) .评估列表理解并创建列表并将其传递;OrderedDict对它是如何创建的一无所知。

        2
  •  81
  •   metatoaster    10 年前
    # An OD is represented by a list of tuples, so would this work?
    d = OrderedDict([('b', 2), ('a', 1)])
    

    是的,这会奏效的。根据定义,列表总是按照其表示方式排序。这也适用于列表理解,生成的列表与提供数据的方式相同(即源于列表,它将是确定性的,源于 set dict 没有那么多)。

    如何验证 OrderedDict 实际上维持着一个秩序。由于一个dict具有不可预测的顺序,如果我的测试向量幸运地具有与dict的不可预测顺序相同的初始顺序,该怎么办?。例如,如果不是 d = OrderedDict({'b':2, 'a':1}) 我在写 d = OrderedDict({'a':1, 'b':2}) ,我可以错误地得出这样的结论:秩序得到了维持。在这种情况下,我发现 字典 是按字母顺序排列的,但这可能并不总是正确的。i、 e.使用反例来验证数据结构是否保持顺序,或者是否不缺少重复尝试测试向量直到一个中断的可靠方法。

    您保留了2元组的源列表以供参考,并在进行单元测试时将其用作测试用例的测试数据。反复检查并确保秩序得到维持。

        3
  •  0
  •   Ataxias    4 年前

    使用生成器表达式也是可能的(而且效率更高):

    d = OrderedDict((i, i) for i in l)
    

    显然,在这种微不足道的情况下,对于 l ,但如果 l级 对应于迭代器或从生成器生成结果,例如用于解析和遍历大型文件,则差异可能非常大(例如避免将整个内容加载到内存中)。例如:

    def mygen(filepath):
        with open(filepath, 'r') as f:
            for line in f:
                yield [int(field) for field line.split()]
    
    d = OrderedDict((i, sum(numbers)) for i, numbers in enumerate(mygen(filepath)))