在python3.6

时间:2017-08-09 04:52:28

标签: python set python-3.6 cpython python-internals

由于Python 3.6中dict实现的更改,现在默认排序。现在set也保留了订单吗?

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

我知道在所有情况下都没有承诺dict被命令,但它们大部分时间都是如此。正如Python文档中所述:

  

此新实现的顺序保留方面被视为实现细节,不应依赖

2 个答案:

答案 0 :(得分:17)

不,set仍然无序。

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

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

如果订购了,您会希望{3, 2, 1}[3, 2, 1]作为示例的结果。

虽然dict实际上是有序的(同样的例子只是有点修改):

>>> 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}

答案 1 :(得分:10)

>>> import string >>> string.digits '0123456789' >>> set(string.digits) {'7', '0', '2', '8', '6', '9', '1', '5', '4', '3'} 未在Python 3.6中排序,甚至不作为CPython实现细节。一个简单的例子说明了这一点:

SELECT * FROM `111_dossier` AS d
LEFT JOIN `008_vehicule` AS v
LEFT JOIN `053_dates` AS da
LEFT JOIN `descriptif` AS des

WHERE (`d.site_gestion` = 57 OR `d.site_creation` = 57)
AND `d.etat_dossier` IN("V","W")
AND year(`da.date_entree`) >= 2014
AND `v.marque` = "Tesla"
AND `des.C4` LIKE %LONGERON% 

Python 3 docs对此很清楚:

  

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