10

假设您有一组:

foo = {1, 2, 3, 4, 5}

在我目前正在阅读的书 Pro Python 中,它说 usingfoo.pop()将从该选择中弹出一个任意数字。但是……当我尝试它时,它pops 1, then 2, then 3...是随意做的,还是这只是巧合?

4

2 回答 2

16

它说它是任意的的原因是因为不能保证它会弹出的顺序。由于您刚刚创建了集合,它可能以“良好”的顺序存储元素,因此.pop()碰巧按该顺序返回它们,但如果您要改变集合,则可能不会继续存在。

例子:

>>> foo = set()
>>> foo.add(-3)
>>> foo.add(-1)
>>> foo.add(2)
>>> foo.pop()
2
>>> foo.pop()
-3
于 2012-03-24T02:43:15.663 回答
15

集合和字典是使用哈希表实现的。它们是无序集合,这意味着它们没有保证顺序。

您看到的订单是非保证的实施细节。在 CPython 中,整数的哈希值就是整数本身:

>>> [hash(i) for i in range(10)]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

该实现细节导致整数在您的集合中显示为有序。其他集合将是半有序的,{5, 6, 7, 8, 9}显示为set([8, 9, 5, 6, 7])

相比之下,其他数据类型(例如str )具有不同的哈希函数,并且看起来更加混乱。例如:

# Example of scrambling str objects in a 64-bit build
>>> {'red', 'green', 'blue'}
set(['blue', 'green', 'red'])

set.pop方法从左到右弹出条目。这也是一个非保证的实现细节。

对您的问题的简短回答是是的,排序是任意的,但是不,您所看到的也不仅仅是巧合,而是一个有趣的非保证实现细节。

希望这能为你解开谜团:-)

于 2012-03-24T02:54:34.547 回答