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