问题描述
在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=…)
保留变量的顺序。