Python dict文字和dict对列表是否保持其键顺序?

问题描述

在Python 3.7+中,字典 literals 是否保持其键的顺序?例如,是否可以保证{1: "one",2: "two"}在其上进行迭代时始终按这种方式排序其键(先是1,然后是2)? (有一个thread in the Python mailing list主题相似,但是它四面八方,我找不到答案。)

类似地,像dict([('sape',4139),('guido',4127),('jack',4098)])这样的字典是否按照列表中的顺序排序?

对于other naturally ordered constructions来说,也是同样的问题,例如dict理解和dict(sape=4139,guido=4127,jack=4098)

PS:据记录为dictionaries preserve insertion order。因此,这个问题实质上是在问:是否保证按照dict文字,列表中的 赋予dict()的顺序插入,等等。>

解决方法

是的,在python 3.7+中,任何构建dict的方法都会保留插入顺序。


有关字典文字,请参见Martijn's answer上的How to keep keys/values in same order as declared?

有关理解,请参见documentation

运行理解后,将生成的键和值元素按它们产生的顺序插入到新字典中。

最后,dict initializer的工作方式是遍历其参数和关键字参数,并依次插入每个参数,类似于:

def __init__(self,mapping_or_iterable,**kwargs):
    if hasattr(mapping_or_iterable,"items"):  # It's a mapping
        for k,v in mapping_or_iterable.items():
            self[k] = v
    else:  # It's an iterable of key-value pairs
        for k,v in mapping_or_iterable:
            self[k] = v

    for k,v in kwargs.items():
        self[k] = v

(这基于source code,但是掩盖了许多不重要的细节,例如dict_init只是dict_update_common的包装。另外请注意,我不知道C,但我明白了要点。)

加上Python 3.6以来关键字参数以相同顺序传递字典 的事实,使得dict(x=…,y=…)保留变量的顺序。