【问题标题】:Do Python dict literals and dict(list of pairs) keep their key order?Python dict 文字和 dict(list of pairs) 是否保持它们的键顺序?
【发布时间】:2020-12-31 12:17:24
【问题描述】:

在 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。因此,这个问题本质上是在问:是否保证数据按 dict 文字的顺序列表dict() 的顺序插入,等等。

【问题讨论】:

  • 这取决于插入的顺序。见stackoverflow.com/questions/39980323/…
  • 您正在阅读他们对字典顺序保留做出最终决定之前的一个帖子。他们现在保持秩序。
  • 这能回答你的问题吗? Are dictionaries ordered in Python 3.6+?
  • 糟糕,我错过了 PS,还以为你不知道它们是按插入顺序排列的。相反,这是否回答了您的问题? How to keep keys/values in same order as declared?
  • @EricOLebigot:PEP 520 和 PEP 468 的结果,都包含在the 3.6 What's New docs 中。 520个保证类属性定义的顺序,468个保留关键字参数顺序。两者都是新紧凑型 dict 实现的副作用,但与 dicts 的一般顺序保留方面不同,它们在 3.6 中成为语言规范的一部分,而不仅仅是实现细节。

标签: python dictionary literals


【解决方案1】:

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


对于 dict 文字,请参阅 How to keep keys/values in same order as declared? 上的 Martijn's answer。另外,来自documentation

如果给出逗号分隔的键/数据对序列,则从左到右对它们进行评估以定义字典的条目:[...]

对于理解,来自same source

运行推导时,生成的键和值元素会按照它们产生的顺序插入到新字典中。

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

【讨论】:

  • Nitpick:它寻找 keys 方法来识别映射,而不是 items。然后它使用items-like 迭代dict 没有覆盖__iter__ 的子类;对于其他所有内容,它会迭代键并查找值。使用items 会更有意义,但我怀疑历史惯性使它使用keys。这些都不会使您的答案无效,因此,仅仅是吹毛求疵。
  • @Shadow 是的,就像我说的,我忽略了很多不重要的细节。很高兴知道您是否正在实现自己的类似映射的类,但我只是想就它的工作原理提供一个简单的高级概念。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-07-10
  • 1970-01-01
  • 1970-01-01
  • 2022-11-10
  • 1970-01-01
  • 2016-09-12
  • 2020-06-24
相关资源
最近更新 更多