【问题标题】:Why does a set of numbers appear to be sorted? [duplicate]为什么一组数字看起来是有序的? [复制]
【发布时间】:2019-02-24 13:14:59
【问题描述】:

多次运行此代码

t = {'a', 'b', 'c', 'd'}
print(t)

可以打印类似:

{'c', 'b', 'a', 'd'} 
{'d', 'b', 'c', 'a'} # different
{'d', 'b', 'c', 'a'} # same
{'a', 'd', 'b', 'c'} # different
{'a', 'b', 'c', 'd'} # different
# etc

(如果您使用控制台复制它,请确保在每次重新粘贴代码并执行它之前单击重新运行。如果仍然无法复制,也许您有hash randomization 不等于 random.On Python 3.3 and greater, hash randomization is turned on by default.)


另一方面,下面的代码总是打印相同的集合,并且实际上是排序的:

s = {1, 6, 3.3, 4}
print(s) 

# prints: 
# {1, 3.3, 4, 6}
# {1, 3.3, 4, 6}
# {1, 3.3, 4, 6}
# {1, 3.3, 4, 6}

问题:
为什么数字集似乎总是被排序并且它们真的是总是排序的?

【问题讨论】:

  • 请注意,set 基本上只是一个没有值的 dict
  • 它似乎只在 iPython 控制台中排序,而不是在普通的 python 控制台中,在迭代它或调用str(s)repr(s) 时。
  • 另一个可能的重复:stackoverflow.com/questions/12165200/…

标签: python set python-3.4


【解决方案1】:

注意,我手边没有 python3.4,但在 python2.7 上并非总是如此(我希望 python3.4 也是如此)。

我什至可以根据我将元素放入集合的方式来更改元素的顺序:

>>> print({1, 9})
set([9, 1])
>>> print({9, 1})
set([1, 9])
>>> set([9, 1])
set([9, 1])
>>> set([1, 9])
set([1, 9])

顺序由元素的散列和​​插入的时间决定(在散列冲突的情况下)。在 CPython 中,整数对其自身进行哈希处理,并且 dict/set 有 8 个空闲插槽可供开始。由于有 8 个可用点,我们可以散列数字 0 -> 7(含)而不会发生散列冲突。但是,如果我们尝试在同一个集合中散列 8 和 0(或 9 和 1),我们会遇到冲突。如果9 已经在集合中,然后我们尝试将1 放入,python 看起来并说“哦,快,那个槽被占用了——现在我需要把它放在下一个最有利的槽中”。冲突解决的细节超出了我的研究范围,所以我无法深入了解这是什么槽......

请注意,如果我们的集合中有超过 5 个元素,那么它将被调整大小(IIRC,到 16,然后是 32,然后是 64,...)这会改变哪些元素会(自然地)发生碰撞。

【讨论】:

  • 不打印会给你一个不同的顺序
  • @PadraicCunningham -- 不确定你的意思?如果我这样做 a = {1, 9}; a 我仍然会得到与 python2.7 上的 print({1, 9}) 相同的东西
  • pastebin.com/yaaS9UbE,从 ipython 运行,这似乎与 python repl 不同
  • @PadraicCunningham -- 您正在使用 IPython,它似乎试图为您提供帮助并对元素进行排序。如果你只打印 repr(s) 会发生什么(这是正常的 python REPL 会做的)?
  • @PadraicCunningham -- 对我来说真正令人惊讶的是{1, 9}set([1, 9]) 给出了不同的结果......出于某种原因,似乎只涉及文字的python 集被向后读取?
猜你喜欢
  • 2012-04-07
  • 1970-01-01
  • 1970-01-01
  • 2020-07-30
  • 2021-02-19
  • 2021-11-12
  • 2012-03-21
  • 2022-07-26
相关资源
最近更新 更多