为什么一组数字看起来是有序的?
Why does a set of numbers appear to be sorted?
运行多次使用此代码
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 not equal to 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}
问题:
为什么数字集看起来总是排序的,而它们真的是 总是 排序的吗?
请注意,我手头没有 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 看起来并说 "Oh snap, that slot's taken -- Now I need to put it in the next most favorable slot"。冲突解决的细节超出了我的研究范围,因此我无法深入了解那是什么插槽...
请注意,如果我们在集合中有超过 ~5 个元素,那么它将调整大小(IIRC,到 16,然后 32,然后 64,......)这会改变哪些元素会(自然地)碰撞。
运行多次使用此代码
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 not equal to 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}
问题:
为什么数字集看起来总是排序的,而它们真的是 总是 排序的吗?
请注意,我手头没有 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 看起来并说 "Oh snap, that slot's taken -- Now I need to put it in the next most favorable slot"。冲突解决的细节超出了我的研究范围,因此我无法深入了解那是什么插槽...
请注意,如果我们在集合中有超过 ~5 个元素,那么它将调整大小(IIRC,到 16,然后 32,然后 64,......)这会改变哪些元素会(自然地)碰撞。