Python dict literals 和 dict(list of pairs) 是否保持它们的键顺序?

Do Python dict literals and dict(list of pairs) keep their key order?

在 Python 3.7+ 中,dict 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(sape=4139, guido=4127, jack=4098)

PS:据记载dictionaries preserve insertion order。因此,这个问题本质上是在问:是否保证数据被插入按照字典文字的顺序, of the list given to dict(),等等

是的,在 Python 3.7+ 中,任何构造字典的方法都会保留插入顺序。


对于 dict 文字,请参阅 Martijn's answer on How to keep keys/values in same order as declared?. Also, from the documentation:

If a comma-separated sequence of key/datum pairs is given, they are evaluated from left to right to define the entries of the dictionary: [...]

为了理解,来自same source

When the comprehension is run, the resulting key and value elements are inserted in the new dictionary in the order they are produced.

最后,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=…) 保留变量的顺序.