由于Python 3.6中dict
实现的更改,现在默认排序。现在set
也保留了订单吗?
我找不到任何关于它的信息,但由于这两种数据结构在它们工作的方式非常相似,我认为可能就是这种情况。
我知道在所有情况下都没有承诺dict
被命令,但它们大部分时间都是如此。正如Python文档中所述:
此新实现的顺序保留方面被视为实现细节,不应依赖
答案 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对此很清楚:
集合是无序集合,没有重复元素。