集合是不是像 python3.6 中的 dicts 一样排序

Posted

技术标签:

【中文标题】集合是不是像 python3.6 中的 dicts 一样排序【英文标题】:Are sets ordered like dicts in python3.6集合是否像 python3.6 中的 dicts 一样排序 【发布时间】:2018-01-16 19:48:23 【问题描述】:

由于 Python 3.6 中 dict 实现的更改,现在默认排序。 sets 现在也保持秩序吗?

我找不到任何关于它的信息,但由于这两种数据结构在它们的底层工作方式上非常相似,我认为可能是这种情况。

我知道dicts 不会在所有情况下都被订购,但大多数情况下都是如此。如 Python 文档中所述:

这个新实现的顺序保留方面被认为是一个实现细节,不应依赖

【问题讨论】:

@byxor 你不应该依赖随机顺序,集合是任意排序的,但由于散列而不是随机的 如果您对 为什么 集合不按插入顺序感兴趣,请参阅Why don't Python sets preserve insertion order? 【参考方案1】:

不,sets 仍然是无序的。

您可以通过显示一个应该具有“明确定义的哈希顺序”的set 来验证这一点1 以确保我们不会意外得到一个看起来有序但实际上的set实际上不是:

>>> a_set = 3,2,1
>>> a_set
1, 2, 3
>>> list(a_set)
[1, 2, 3]

如果已订购,您会期望 3, 2, 1[3, 2, 1] 作为示例的结果。

虽然dicts 实际上是有序的(相同的例子只是稍作修改):

>>> a_dict = 3: 3, 2: 2, 1:1
>>> a_dict
3: 3, 2: 2, 1: 1
>>> list(a_dict)
[3, 2, 1]

1 “定义明确的哈希顺序”:

对于满足0 <= integer < sys.hash_info.modulus 的整数,hash 只是数字本身。这意味着如果集合是根据散列“基于”排序(而不是基于插入“时间”排序)并且散列值不冲突(这就是我使用小数字和仅相差一个的数字的原因)顺序应该是确定性的,因为它们占据了集合中彼此相邻的插槽:

从小到大 或从特定值到最高值,然后从最小值到特定值。如果集合中的下一个(在相邻的意义上)空闲槽位是第一个空闲槽位,则会发生这种情况。

以后者为例:

>>> a_set = 6,7,8,9
>>> a_set
8, 9, 6, 7

【讨论】:

Negative ints 也对自己进行哈希处理(-1 除外),尽管我不确定确切的下限是多少 @Chris_Rands 是的,但是因为 -1-2 都哈希到 -2 有一个冲突。:) 是的,-1 这样做是因为它是 C 语言中的错误代码;我相信边界是(sys.maxsize // 4) - 1,至少这是Martijn Pieters之前告诉我的 很高兴知道。但如果想在hash 期间捕获错误,这是有道理的。我还找到了最大值。这是sys.hash_info.modulus。 :)【参考方案2】:

sets 在 Python 3.6 中没有排序,甚至没有作为 CPython 实现细节。一个简单的例子说明了这一点:

>>> import string
>>> string.digits
'0123456789'
>>> set(string.digits)
'7', '0', '2', '8', '6', '9', '1', '5', '4', '3'

Python 3 docs 对此很清楚:

集合是没有重复元素的无序集合。

【讨论】:

dict 上的文档也说“最好将字典视为 无序 键:值对集,并要求键是唯一的(在一本字典中)。” (source)。这只是语言规范,可以订购实现... @MSeifert “最好考虑”是我认为的关键措辞,set 文档没有这样的警告 我认为这只是“绒毛”(或包括在内,因为 PyPy 长期以来一直有一个有序的字典)。但是,就像我说的,这只是语言规范。这并不意味着实现可以以有序的方式实现它(即使用存储桶或类似方式)。 评论已过时,现在从文档的该部分中删除了“无序”一词。 我认为在 python 3.6 文档中的措辞保持不变docs.python.org/3.6/tutorial/datastructures.html#dictionaries

以上是关于集合是不是像 python3.6 中的 dicts 一样排序的主要内容,如果未能解决你的问题,请参考以下文章

python3.6 判断字典是不是有某个key

dict--新华字典,没有新华

Python3中对Dict的内存优化

python实现字典遍历稳定有序使用collection包OrderedDict

[Python 3系列]字典

python3.6 创建字典三法