1. 概述
集合set数据结构/数据类型和list类似,都是存储一系列的数据或对象,且可以是各种数据类型的数据。和list最大的区别在于,set是无序的,且set中的元素唯一。
在处理一系列数据时,如果需要剔除重复项,则通常采用set数据类型。
Python中集合set的概念和离散数学中集合的概念是完全一致的,也有交集、并集、子集等各种算法。——当然,日常工作未必会用到所有这些。
2. 参考资料
如下:
- https://docs.python.org/2/library/sets.html
- 4. Built-in Types 4.9. Set Types — set, frozenset
- Programming Python, 3rd Edition.chm:20.3. Implementing Sets; 第4版是第18章,下载链接:
3. 常用算法
集合分为可变集合set和不可变集合frozenset,本文(暂)仅讨论可变集合。
3.1 定义一个集合
列表是用一对中括号表示、字典dict是用一对花括号表示、元组是一对圆括号表示,如此,括号被占用完了。没有办法,所以集合的定义较为特殊,用set()来初始化一个集合对象。
下面这个例子是先初始化一个set对象,然后调用add()方法不断增加元素:
>>> s = set()
>>> s
set([])
>>> s.add(1)
>>> s
set([1])
>>> s.add(1)
>>> s
set([1])
>>> s.add(10)
>>> s
set([1, 10])
>>> s.add(5)
>>> s
set([1, 10, 5])
>>>
前面已经提到,和list一样,set对象中的数据类型不要求是完全一样的,示例如下:
>>> s = set()
>>> s.add(1)
>>> s.add("one")
>>> s
set([1, 'one'])
>>>
3.2 用列表来初始化一个集合对象
>>> list = [1, 2, 3, "one", "two", "three"]
>>> s = set(list)
>>> s
set([1, 2, 3, 'three', 'two', 'one'])
>>>
>>> string = "Hello, world!"
>>> s2 = set(string)
>>> s2
set(['!', ' ', 'e', 'd', 'H', 'l', 'o', ',', 'r', 'w'])
>>>
3.3 增加一个元素
如3.1节的代码,set是用add()方法增加一个元素。
如果要增加多个元素、或者把另外一个集合中的元素添加过来,则使用集合的并集算法。
3.4 集合的无序性
集合中元素的顺序并非按照每个元素添加进去的顺序来排列,如下:
>>> s = set()
>>> s.add(3)
>>> s
set([3])
>>> s.add(1)
>>> s
set([1, 3])
>>> s.add(5)
>>> s
set([1, 3, 5])
>>>
>>>
>>> s.clear()
>>> s
set([])
>>> s.add("one")
>>> s.add("two")
>>> s
set(['two', 'one'])
>>> s.add("three")
>>> s
set(['three', 'two', 'one'])
>>>
因为无序这一特征,所以set没有list、string等有序对象的索引表示方法,如:
>>> s = set([1,2,3])
>>> s
set([1, 2, 3])
>>> s[1]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'set' object does not support indexing
>>>
3.5 集合元素的个数
计算set对象中元素的格式,使用的是len()函数。——set本身没有len()方法或者size()方法,尽管size()这个名称更加合适(如C++ STL中list、vector)。
>>> s
set([1, 2, 3])
>>> s.len()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'set' object has no attribute 'len'
>>> len(s)
3
>>> s.size()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'set' object has no attribute 'size'
>>>
>>> len(s)
3
>>>
3.6 遍历元素
和list一样,可以用for来遍历集合中的每一个元素:
>>> s
set([1, 10, 5])
>>> for x in s:
... print x
...
1
10
5
>>>
3.7 排序
前面已经提到,集合对象的存储是无序的,因此,也没有list对象的sort()方法可供调用。但要从一个set对象得到有序的元素序列,则可以先把set对象转换成list对象,然后调用list对象的sort()方法。
>>> s = set(["first", "second", "three", "four", "five"])
>>> s
set(['four', 'second', 'five', 'three', 'first'])
>>> list_of_s = list(s)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'list' object is not callable
>>> del list
>>> list_of_s = list(s)
>>> list_of_s
['four', 'second', 'five', 'three', 'first']
>>> list_of_s.sort()
>>> list_of_s
['first', 'five', 'four', 'second', 'three']
>>>
如果顺着前面的例子一路下来,这里会有异常。因为前面我们有个例子是把list作为一个变量名称,因此需要先del这个对象。然后Python解释器才认为list是关键字/内置函数。
3.8 集合的差
source - target: 从source中删除在target中出现的元素。
>>> source = set(['first', 'second', 'third'])
>>> target = set(['first', 'forth'])
>>> source
set(['second', 'third', 'first'])
>>> target
set(['forth', 'first'])
>>> to_be_removed = source - target
>>> to_be_removed
set(['second', 'third'])
>>>
3.9 并集
并集的运算符号是|。普通的加号(+)是不能用于set对象的。
>>> source = set(['first', 'second', 'third'])
>>> target = set(['first', 'forth'])
>>> source
set(['second', 'third', 'first'])
>>> target
set(['forth', 'first'])
>>> merged = source | target
>>> merged
set(['second', 'forth', 'third', 'first'])
>>> add = source + target
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unsupported operand type(s) for +: 'set' and 'set'
>>>