当前位置: 首页 > 面试题库 >

无序Python集的“顺序”

斜高翰
2023-03-14
问题内容

我知道Python中的集合是无序的,但是我很好奇它们显示的“顺序”,因为它看起来是一致的。每次它们似乎都以相同的方式乱序:

>>> set_1 = set([5, 2, 7, 2, 1, 88])
>>> set_2 = set([5, 2, 7, 2, 1, 88])
>>> set_1
set([88, 1, 2, 5, 7])
>>> set_2
set([88, 1, 2, 5, 7])

…还有另一个例子:

>>> set_3 = set('abracadabra')
>>> set_4 = set('abracadabra')
>>> set_3
set(['a', 'r', 'b', 'c', 'd'])
>>>> set_4
set(['a', 'r', 'b', 'c', 'd'])

我很好奇为什么会这样。有什么帮助吗?


问题答案:

你应该观看此视频(尽管它是CPython 1特定的并且是关于字典的-但我认为它也适用于集合)。

基本上,python对元素进行哈希处理并获取最后N位(其中N由集合的大小确定),然后将这些位用作数组索引以将对象放置在内存中。然后按照它们在内存中存在的顺序产生对象。当然,当你需要解决哈希之间的冲突时,图片会稍微复杂一些,但这就是要点。

还要注意,它们的打印顺序取决于你放置它们的顺序(由于碰撞)。因此,如果你对传递给的列表进行重新排序set_2,那么在发生键冲突时,你可能会得到其他排序。

例如:

list1 = [8,16,24]
set(list1)        #set([8, 16, 24])
list2 = [24,16,8]
set(list2)        #set([24, 16, 8])

请注意,顺序保留在这些集合中的事实是“巧合”,并且与冲突解决有关(我一无所知)。问题的关键是,最后3位hash(8),hash(16)并且hash(24)是相同的。因为它们是相同的,所以冲突解决方案将接管并将元素放置在“备份”存储位置中,而不是首先(最佳)选择中,因此,是否8占据某个位置或16由哪个位置首先到达聚会并获得“最佳”决定座位”。

如果用和重复该示例1,则无论输入列表中的顺序如何,你都将获得一致的顺序:23

list1 = [1,2,3]
set(list1)      # set([1, 2, 3])
list2 = [3,2,1]
set(list2)      # set([1, 2, 3])

因为最后3位hash(1)hash(2)并且hash(3)是唯一的。

1 注意此处描述的实现适用于CPython dictset。我认为一般说明对所有最新版本的CPython到3.6均有效。但是,从CPython3.6开始,还有一个附加的实现细节,实际上保留了的迭代插入顺序dict。似乎set仍然没有此属性。pypy的人(在CPython的人之前开始使用它)在此博客文章中描述了数据结构。最初的想法(至少对于python生态系统而言)存储在python-dev邮件列表中。



 类似资料:
  • 问题内容: 我不了解Python从保持集中应用的顺序。例如: 的顺序是。为什么“ A”在“ C”之前(可能是字母顺序)?为了保留添加顺序,我必须做什么? 问题答案: 您不能有订单集。而且没有办法告诉Python如何订购它。检查此答案以找到替代方法。

  • 问题内容: 我想知道Python内置结构的元素排序是否不足够“随机”。例如,采用集合的迭代器,是否可以将其视为其元素的混合视图? (如果很重要,我将在Windows主机上运行Python 2.6.5。) 问题答案: 不,这 不是 随机的。它是“任意排序”的,这意味着您不能依赖于它是随机的还是随机的。

  • 问题内容: 我首先来看看Python Wikibook 中的python语言。 对于集,提到了以下内容: 我们还可以循环移动一组中的每个项目。但是,由于集合是无序的,因此无法确定迭代将遵循的顺序。 和给出的代码示例是: 输出: 当我运行该程序时,无论运行多少次,我都将以相同的顺序获得结果。如果集合是无序的并且迭代的顺序是不确定的,为什么它以相同的顺序返回集合?订单的依据是什么? 问题答案: 它们不

  • 问题内容: 我需要为测试设置执行顺序,因为我需要先验证一些数据。可以下订单吗? 谢谢 问题答案: 最好不要这样做。 测试应该是独立的。 要做您最想做的就是将代码放入测试调用的函数中。 像那样: 甚至拆分测试类,并将断言放入setUp函数中。 当我拆分班级时,我经常编写更多更好的测试,因为测试被拆分,并且在应该测试的所有情况下我都能看到更好的结果。

  • 问题内容: 码: 打印。我不确定该方法如何确定l中关键字的顺序。但是,我希望能够以“适当”的顺序检索关键字。当然,正确的顺序将创建列表。 和这个: 问题答案: 你可以使用OrderedDict(需要Python 2.7)或更高版本。 另外,请注意,由于dict你使用进行创建的操作已经忘记了元素的顺序,因此该操作无效。相反,你想使用。 如文档中所述,对于低于python 2.7的版本,你可以使用此配

  • 问题内容: 我正在寻找一个有序的关联数组,即有序的字典的可靠实现。我想要按键而不是插入顺序排序。 更准确地说,我正在寻找一种int-to-float(或另一种用例是string-to-float)映射结构的节省空间的实现,该结构的结构是: 有序迭代为O(n) 随机访问为O(1) 我想到的最好的方法是将字典和键列表粘合在一起,使最后一个键按等分和插入顺序排列。 还有更好的主意吗? 问题答案: “随机