Due to changes in dict
implementation in Python 3.6 it is now ordered by default. Do set
s preserve order as well now?
由于Python 3.6中命令的实现发生了变化,现在默认情况下是命令。现在集合也能保持秩序吗?
I could not find any information about it but as both of those data structures are very similar in the way they work under the hood I thought it might be the case.
我找不到任何关于它的信息,但由于这两种数据结构都非常相似,我认为可能是这样。
I know there is no promise for dict
s to be ordered in all cases but they are most of the time. As stated in Python docs:
我知道在任何情况下都不会有命令的承诺,但大多数时候都是这样。如Python文档中所述:
The order-preserving aspect of this new implementation is considered an implementation detail and should not be relied upon
这个新实现的订单保存方面被认为是实现细节,不应该依赖它
2 个解决方案
#1
5
set
s are not ordered in Python 3.6, not even as a CPython implementation detail. A simple example illustrates this:
在Python 3.6中,集不是有序的,即使是CPython实现的细节也是如此。一个简单的例子说明了这一点:
>>> import string
>>> string.digits
'0123456789'
>>> set(string.digits)
{'7', '0', '2', '8', '6', '9', '1', '5', '4', '3'}
The Python 3 docs are clear on this:
Python 3文档对此很清楚:
A set is an unordered collection with no duplicate elements.
集合是没有重复元素的无序集合。
#2
5
No, set
s are still unordered.
不,集合仍然是无序的。
You can verify this just by displaying a set
that should have a "well-defined hash order"1 to make sure we don't accidentally get a set
that looks ordered but actually isn't:
你可以通过显示一个应该有“定义良好的哈希顺序”1的集合来验证这一点,以确保我们不会意外地得到一个看起来有序但实际上不是有序的集合:
>>> a_set = {3,2,1}
>>> a_set
{1, 2, 3}
>>> list(a_set)
[1, 2, 3]
If it were ordered you would expect {3, 2, 1}
and [3, 2, 1]
as result of the examples.
如果它是有序的,那么您将期望{3,2,1}和[3,2,1]作为示例的结果。
While dict
s are actually ordered (same example just a bit modified):
而命令实际上是有序的(同样的例子只是稍微修改一下):
>>> a_dict = {3: 3, 2: 2, 1:1}
>>> a_dict
{3: 3, 2: 2, 1: 1}
>>> list(a_dict)
[3, 2, 1]
1 "well-defined hash order":
1“定义良好的散列秩序”:
For integers that satisfy 0 <= integer < sys.hash_info.modulus
the hash
is just the number itself. That means if the set is ordered "based" on the hash (and not ordered based on the insertion "time") and the hash values don't collide (that's why I used small numbers and numbers that only differ by one) the order should be deterministic because they occupy slots inside the set that are next to each other:
对于满足0 <= integer < sys.hash_info的整数。模数哈希就是数字本身。这意味着如果一组命令”“基于哈希(而不是命令基于插入“时间”)和散列值不发生碰撞(这就是为什么我使用小数字和数字,只相差一个)的顺序应该是确定的,就是因为他们占据了槽内相邻的设置:
- Either from smallest to highest
- 从最小到最高
- or a from a specific value to the highest and then from the smallest to the specific value. This case happens if the next (in the sense of neighboring) free slot in the set is the first one.
- 或者a从一个特定值到最高,然后从最小值到特定值。如果集合中的下一个(在邻近的意义上)空闲插槽是第一个插槽,就会发生这种情况。
As an example for the latter:
作为后者的一个例子:
>>> a_set = {6,7,8,9}
>>> a_set
{8, 9, 6, 7}
#1
5
set
s are not ordered in Python 3.6, not even as a CPython implementation detail. A simple example illustrates this:
在Python 3.6中,集不是有序的,即使是CPython实现的细节也是如此。一个简单的例子说明了这一点:
>>> import string
>>> string.digits
'0123456789'
>>> set(string.digits)
{'7', '0', '2', '8', '6', '9', '1', '5', '4', '3'}
The Python 3 docs are clear on this:
Python 3文档对此很清楚:
A set is an unordered collection with no duplicate elements.
集合是没有重复元素的无序集合。
#2
5
No, set
s are still unordered.
不,集合仍然是无序的。
You can verify this just by displaying a set
that should have a "well-defined hash order"1 to make sure we don't accidentally get a set
that looks ordered but actually isn't:
你可以通过显示一个应该有“定义良好的哈希顺序”1的集合来验证这一点,以确保我们不会意外地得到一个看起来有序但实际上不是有序的集合:
>>> a_set = {3,2,1}
>>> a_set
{1, 2, 3}
>>> list(a_set)
[1, 2, 3]
If it were ordered you would expect {3, 2, 1}
and [3, 2, 1]
as result of the examples.
如果它是有序的,那么您将期望{3,2,1}和[3,2,1]作为示例的结果。
While dict
s are actually ordered (same example just a bit modified):
而命令实际上是有序的(同样的例子只是稍微修改一下):
>>> a_dict = {3: 3, 2: 2, 1:1}
>>> a_dict
{3: 3, 2: 2, 1: 1}
>>> list(a_dict)
[3, 2, 1]
1 "well-defined hash order":
1“定义良好的散列秩序”:
For integers that satisfy 0 <= integer < sys.hash_info.modulus
the hash
is just the number itself. That means if the set is ordered "based" on the hash (and not ordered based on the insertion "time") and the hash values don't collide (that's why I used small numbers and numbers that only differ by one) the order should be deterministic because they occupy slots inside the set that are next to each other:
对于满足0 <= integer < sys.hash_info的整数。模数哈希就是数字本身。这意味着如果一组命令”“基于哈希(而不是命令基于插入“时间”)和散列值不发生碰撞(这就是为什么我使用小数字和数字,只相差一个)的顺序应该是确定的,就是因为他们占据了槽内相邻的设置:
- Either from smallest to highest
- 从最小到最高
- or a from a specific value to the highest and then from the smallest to the specific value. This case happens if the next (in the sense of neighboring) free slot in the set is the first one.
- 或者a从一个特定值到最高,然后从最小值到特定值。如果集合中的下一个(在邻近的意义上)空闲插槽是第一个插槽,就会发生这种情况。
As an example for the latter:
作为后者的一个例子:
>>> a_set = {6,7,8,9}
>>> a_set
{8, 9, 6, 7}