dict.keys() 和 dict.values() 保证什么顺序?

What ordering does dict.keys() and dict.values() guarantee?

This question arises from this answer where one user uses d.keys() and d.values() separately to initialise a dataframe.

众所周知,python 3.6 以下版本的词典没有排序。

考虑以下形式的通用字典:

d = {k1 : v1, k2 : v2, k3 : v3}

其中键 k* 是任何可哈希对象,值 v* 是任何对象。当然不能保证顺序,但是d.keys()d.values()的顺序呢?

Python 2.x

d.keys()d.values() return 列表。比如说,.keys() returns d 的键的顺序是 [k2, k1, k3]。现在 总是保证 d.values() return 与 [v2, v1, v3] 的相对顺序相同吗?此外,无论这些函数被调用多少次,顺序是否保持不变?

Python 3.x (<3.6)

我不是 100% 确定,但我相信 .keys.values 不能保证这里的任何顺序,因为它们是类似集合的结构,因此没有定义的顺序并使您能够对它们执行类似集合的操作。但我仍然想知道在这种情况下,两个调用之间是否存在 any 类相对顺序。 我猜不是。 如果有人能肯定或纠正我,我将不胜感激。

一般规则:

  1. 在讨论什么是有保证的和什么不是保证之前,即使某些顺序看起来是 "guaranteed",但事实并非如此。你不应该依赖它。这被认为是不好的做法,并可能导致严重的错误。
  2. d.keys()d.values()d.items() 所有 return 元素均按各自的顺序排列。该顺序应被视为任意顺序(不应对此做出任何假设)。 (docs)
  3. d.keys()d.values()d.items() 的连续调用是 "stable",从某种意义上说,它们保证保留先前调用的顺序(假设没有 insertion/deletion 发生在调用之间)。
  4. 从 CPython 的 V3.6 开始,dict has been reimplemented,它现在保留了 插入 顺序。这不是更改的目标,而是副作用,它不是 python 规范的一部分,只是 CPython 实现的细节。请参见上面的第 1 点:依赖于此是不好的做法,不应这样做。无论如何,您应该避免编写特定于 CPython 的代码。
  5. 在Python2中,顺序是确定性的(即以相同的方式两次创建字典将产生相同的顺序)。在 Python <3.6 中,它不再是确定性的,所以你也不能依赖它(我不确定这种非确定性是规范的一部分还是只是 CPython 实现细节)。

编辑:添加第 5 点,感谢@AndyHayden 的评论。