集合(set)
(1)集合的元素
(2)集合的构造
(3)集合的操作**
写在前面:
- 集合的概念来源于数学,因此,python的集合同样支持元素的判断,也支持各种重要的集合操作,并集、交集、差集等。
- 表达式:{元素,…}
- 空集合:set{}(注意:这里不能直接使用{},{}表示的是空字典)
- python由两个表示集合的类型:set 和 frozenset(冻结集合)。两者的不同之处在于set是可变类型,而frozenset是不变类型。
- 要生成frozenset的对象,只能用frozenset(…)的形式。
接下来主要介绍set,与元素变动无关的均适用于frozenset。
集合的元素
- 集合的元素只能是不变对象,而且必须能做相等比较(用 == 运算符)。内置的数值类型、字符串、bool对象,及他们的元组等都满足这些要求。
- 元素对象具有唯一性,不会出现重复元素,元素之间也没有顺序关系。
e.g.>>>{6,6,2,2,7,7,4,4,5,5} {2,4,5,6,7}
集合的构造
-
直接描述
e.g.>>>{'math', 'Math', 'MATH', 'phys', 'Phys'} {'phys', 'MATH', 'math', 'Phys', 'Math'}
注意:元素的排列是不能控制的
-
set(…)转换
从任意的序列或可迭代对象生成相应的集合
e.g.>>>set([3,7,5,4,9]) {3, 4, 5, 7, 9}
-
用描述式生成集合
{生成器表达式}
e.g.>>> s = {x for x in range(5)} {0, 1, 2, 3, 4}
-
类型转换
tuple
如果一个tuple的元素总能用 == 比较,就可以从它转换得到一个set对象,但顺序丢失,重复元素消去。另一方面,一个set对象总能转换得到一个tuple对象。
list
如果一个list里的元素都满足set对元素的要求,就可以从这个list转换得到一个set对象,但表对象的顺序丢失,消除了重复元素。另一方面,一个set对象,总能转换得到一个表对象。
字符串
任何字符串可以转换得到一个集合,其中的元素就是原字符串中单个字符的串,消去重复字符,顺序内定。从集合转换得到字符串得到集合的字符串表示,意思完全不同。 -
特殊状况
>>>set() is set() False #两次生成的空集合(set)不是同一个对象 >>>frozenset() is frozenset() True #不会创建两个不同的不变空集 >>>{1, 1.0} #python认为数值1与1.0等值 {1.0} >>>{1.0, 1} {1} >>>{1, True} #python认为True和1等值,False和0等值 {True} >>>{False, 0} {0}
集合的操作
标准操作
序列 | 表达式 | 意义 |
---|---|---|
1 | len(s) | 求集合长度,即集合内元素个数 |
2 | x in s ; x not in s | 判断x是否在集合s内,是返回True,否则返回False;not in 反之 |
3 | for x in s: …x… | 集合可作为可迭代对象使用,取得元素顺序由集合内部实现确定 |
4 | sorted(s) | 得到集合元素排序的表 |
简单实例
#len(s)
>>>s = {1,2,3,4,5,6,7,8,9}
>>>len(s)
9
#x in s ; x not in s
>>>s = {1,2,3,4,5}
>>>3 in s
True
>>>9 in s
False
#for x in s: ....x...
>>>s = {2,7,1,'a','s','d'}
>>>for x in s:
print(x)
1
2
s
7
a
d
#sorted(s)
>>>s = {1,5,7,2,4,5}
>>>sorted(s)
[1, 2, 4, 5, 7]
>>>s = {'a','d','z','y','m'}
>>>sorted(s)
['a', 'd', 'm', 'y', 'z']
#调用sorted(s)时,s里不能同时用str和int,否则会报错
>>>s = {1,3,'a','d'}
>>>sorted(s)
Traceback (most recent call last):
File "<pyshell#28>", line 1, in <module>
sorted(s)
TypeError: '<' not supported between instances of 'int' and 'str'
集合的比较
序列 | 表达式 | 意义 |
---|---|---|
1 | s1 <= s2 ; s1.issubset(s2) | 当且仅当s1为s2子集时返回True |
2 | s1 < s2 | 当且仅当s1为s2的真子集时得到True;真子集说明s2至少包含一个不属于s1的元素 |
3 | s1 > = s2 ; s1.issuperset(s2) | 判断s1是否为s2的超集 |
4 | s1 > s2 | 判断s1是否为s2的真超集 |
5 | s1.isdisjoint(s2) | 判断两个集合是否不想交,即有没有公共元素 |
简单实例
>>>s1 = {1,2,3,4,5,6,7,8,9,10}
>>>s2 = {2,4,6,8,10}
>>>s1 <= s2
False
>>>s1 < s2
False
>>>s1 >= s2
True
>>>s1 > s2
True
>>>s1.isdisjoint(s2)
False
集合运算
序列 | 表达式 | 意义 |
---|---|---|
1 | s1.union(s2, …) ; s1/ s2(直线) | 并集,生成新集合 |
2 | s1.intersection(s2, …) ; s1 & s2 & … | 交集,生成新集合 |
3 | s1.difference(s2, …) ; s1 -s2 - … | 生成第一个集合减去后面集合的差集 |
4 | s1.symmetric_difference(s2) | 生成s1和s2的对称差集,包含属于s1但不属于s2,属于s2但不属于s1(即并集与交集的差集) |
5 | s1.copy() | 生成s1的拷贝 |
简单实例
>>>s1 = {1,2,3,4,5,6,7,8,9,10}
>>>s2 = {2,4,6,8,10,12,14,16}
>>>s1 | s2 #表格里因无法输入 | 显示的是 \ ,正确使用时应用 |
{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12, 14, 16}
>>>s1 & s2
{2, 4, 6, 8, 10}
>>>s1 - s2
{1, 3, 5, 7, 9}
>>>s1.symmetric_difference(s2)
{1, 3, 5, 7, 9, 12, 14, 16}
>>>s1.copy()
{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
tip: 对于非运算符形式的集合运算,比如s.union(…),其实参可以是任意可迭代对象。采用运算符的形式时参数必须是集合。
修改集合
序列 | 表达式 | 意义 |
---|---|---|
1 | s.add(x) | 将元素x加入集合s |
2 | s.remove(x) | 从s里删除元素x,若s里无x报错 |
3 | s.discard(x) | 如果s里有x,抛弃,若无则什么都不做 |
4 | s.pop() | 从s里删除某个(任意的)元素并返回它,具体元素由集合内部确定。若s空,将报错 |
5 | s.clear() | 清除s里的所有元素 |
简单实例
>>>s = {1,7,9,'c','e',5,'s'}
#s随操作不断更新
>>>s.add(2)
>>>s
{1, 2, 's', 5, 'e', 7, 9, 'c'}
>>>s.remove('c')
>>>s
{1, 2, 's', 5, 'e', 7, 9}
>>>s.discard(1)
>>>s
{2, 's', 5, 'e', 7, 9}
>>>s.pop()
2
>>>s
{'s', 5, 'e', 7, 9}
>>>s.clear()
>>>s
set()
集合更新操作
序列 | 表达式 | 意义 |
---|---|---|
1 | s1.update(s2, …) ; s1 /=s2 /…(直线) | 修改s1,使之包含属于其他集合的元素 |
2 | s1.intersection_update(s2, …) ; s1 &= s2 & … | 修改s1,使之只包含同属所有集合的公共元素 |
3 | s1.differnence_update(s2, …) ; s1 -=s2 / … | 修改s1,从中去除属于其他集合的元素 |
4 | s1.symmetric_difference_update(s2) | 修改s1,使之只包含仅属于s1或s2之一但不同时属于两者的元素 |
简单实例
>>>s1 = {1,2,3,4,5,6,7,8,9,10}
>>>s2 = {2,4,6,8,10,12,14,16}
>>>s1 |= s2
>>>s1
{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12, 14, 16}
>>>s1 &= s2
>>>s1
{2, 4, 6, 8, 10, 12, 14, 16}
>>>s1 -= s2
>>>s1
set()
>>>s1.symmetric_difference_update(s2)
{2, 4, 6, 8, 10, 12, 14, 16}