2013-03-03 60 views
34

在python中,set()是一个没有重复元素的无序集合。但是,我无法理解它是如何生成输出的。了解set()函数

例如,请考虑以下几点:

>>> x = [1, 1, 2, 2, 2, 2, 2, 3, 3] 
>>> set(x) 
set([1, 2, 3]) 

>>> y = [1, 1, 6, 6, 6, 6, 6, 8, 8] 
>>> set(y) 
set([8, 1, 6]) 

>>> z = [1, 1, 6, 6, 6, 6, 6, 7, 7] 
>>> set(z) 
set([1, 6, 7]) 

不应该的set(y)输出是:set([1, 6, 8])?我在Python 2.6中尝试了以上两个。

+35

你自己说一个集合是一个*无序集合* ... – Volatility 2013-03-03 02:40:11

回答

50

集合是无序的,像你说的。尽管实现集合的一种方法是使用树,但它们也可以使用散列表来实现(这意味着以排序顺序获取键可能不是那么简单)。

如果您想对它们进行排序,你可以简单地执行:

sorted(set(y)) 

这将产生含集合的元素排序列表。 (不是集合,再次,集合是无序的。)

否则,set保证唯一的事情是它使元素唯一(没有什么会多于一次)。

希望这会有所帮助!

+2

注意:集合通常可以使用树来实现。在Python中'set'不能(有意义),因为它保证了它们需要物品可以被哈希,并且不需要它们具有可比性。 – delnan 2013-03-03 02:48:32

+0

@delnan好的一点。 – user 2013-03-03 02:51:35

+1

@delnan - 并且要清楚地说明,*可比较*您的意思是*丰富的比较*('<', '>')。为了使对象成为“可哈”,它必须实现'__eq__'。 – mgilson 2013-03-03 02:52:36

6

As +挥发性和你自己指出的,集合是无序的。如果你需要的元素是为了,只需拨打sorted在集:

>>> y = [1, 1, 6, 6, 6, 6, 6, 8, 8] 
>>> sorted(set(y)) 
[1, 6, 8] 
11

作为无序收集类型,set([8, 1, 6])相当于set([1, 6, 8])

虽然按排序顺序显示设置内容可能更好,但这会使repr()调用更加昂贵。

在内部,set类型是使用散列表实现的:使用散列函数将项目分隔为多个存储区,以减少检查项目是否为该组的一部分所需的相等操作的数量。

要生成repr()输出,它只是依次输出来自每个存储桶的项目,这不太可能是排序顺序。

4

Python的集合(和字典)会迭代并打印出的某些顺序,但是确切的顺序将是任意的,并且不保证在添加和移除后保持不变。

下面是一组有很多值之后,添加和删除,然后切换顺序的一个例子:

>>> s = set([1,6,8]) 
>>> print(s) 
{8, 1, 6} 
>>> s.update(range(10,100000)) 
>>> for v in range(10, 100000): 
    s.remove(v) 
>>> print(s) 
{1, 6, 8} 

这是实现相关的,虽然,所以你不应该依赖于它。

1

我今天问了同样的问题,并得到了downvoted并链接到这个答案。我仍然有困难了解为什么该集合出来无序。

向我的合伙人提到了这一点,他提出了这个比喻:拿大理石。你把它们放在比大理石宽度稍宽的管中:你有一个列表。不过,一套是一个包。即使你把弹珠一个接一个地放进袋子里,当你将它们从袋子倒入管子时,它们将不会按照相同的顺序排列(因为它们都混在一起)。