集合的定义
集合里面是没有重复元素的
使用集合工厂函数set()来定义一个空的集合
s = set()
使用 { } 来定义一个有数据的集合
s = {1,2,3,4}
使用工厂函数set定义一个迭代对象集合
s = set(range(3))
集合的操作
增加元素
>>> s
{0, 1, 2}
>>> s.add(3) 和列表的append方法类似,增加单个元素,是原地修改
>>> s
{0, 1, 2, 3}
>>> s
{0, 1, 2, 3}
>>> s.add(3) 增加了一个已经存在的元素的时候,不会有任何操作
>>> s
{0, 1, 2, 3}
>>> s
{0, 1, 2, 3}
>>> s.update(range(4,7)) update是将一个迭代对象追到尾部,原地修改,和列表的extend类似
>>> s
{0, 1, 2, 3, 4, 5, 6}
>>> s
{0, 1, 2, 3, 4, 5, 6}
>>> s.update(range(4,9)) 对于已经存在的元素,不做任何处理,但是没有的元素,会添加到集合的尾部
>>> s
{0, 1, 2, 3, 4, 5, 6, 7, 8}
删除元素
>>> s.remove(0) remove 删除指定元素
>>> s
{1, 2, 3, 4, 5, 6, 7, 8}
>>> s
{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
>>> s.remove(10) 当删除一个不存在的元素的时候,会抛出KeyError的错误
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
KeyError: 10
>>> s.pop()
1
>>> s
{2, 3, 4, 5, 6, 7, 8}
>>> s.pop() pop 是“随机”删除一个元素,直到集合为空为止
2
>>> s
{3, 4, 5, 6, 7, 8}
>>> s
{3, 4, 5, 6, 7, 8}
>>> s.clear() 清空一个集合
>>> s
set()
>>> s
set()
>>> s.pop() 当集合为空的时候,使用pop方法的时候会抛出KeyError的错误
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
KeyError: 'pop from an empty set'
>>> s
{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
>>> s.discard(3)
>>> s
{0, 1, 2, 4, 5, 6, 7, 8, 9}
>>> s.discard(10) discard方法删除元素的时候,当元素不存在的时候,不做任何操作
>>> s
{0, 1, 2, 4, 5, 6, 7, 8, 9}
修改元素
- 集合不能修改单个元素
查找集合
- 集合不能通过索引操作
- 集合没有访问单个元素的方法
- 集合不是线性结构,集合元素没有顺序
成员运算符
- in
- not in
成员运算符,用于判断一个元素是否在容器中
>>> s = list(range(5))
>>> 1 in s
True
>>> 10 in s
False
in 用于判断元素是否存在于对象中的,存在是True,不存在是False
>>> s
[0, 1, 2, 3, 4]
>>> 1 not in s
False
>>> 10 not in s
True
not in 刚好和in相反,当元素存在于对象中的时候是False,不存在则为True
集合的成员运算符和其他线性结构的成员运算符的时间复杂度不同的
做成员运算符的时候,集合的效率远高于列表
做成员运算符的时候,集合的效率和集合的规模无关
做成员运算符的时候,列表的效率和列表的规模有关
成员运算:
集合: O(1)
列表(线性结构):O(n)
当数据规模比较大的时候,可以将线性结构转成集合来做成员运算,但是当数据量并非很大的时候,集合的效率未必有线性结构的成员运算快,因此若是数据量小,就不要转成集合了
成员运算符的返回值都是布尔类型
集合的运算
交集
>>> s1 = {1,2,3}
>>> s2 = {2,3,4}
>>> s1.intersection(s2)
{2, 3}
intersection方法是将s1和s2的相同元素返回,不是原地修改的
>>> s1.intersection_update(s2)
>>> s1
{2, 3}
>>> s2
{2, 3, 4}
原地修改返回None,等效于 s1 = s1.intersection(s2)
>>> s1
{1, 2, 3}
>>> s2
{2, 3, 4}
>>> s1 & s2 set 重载了按位于运算符为求交集运算,等效于s2.intersection(s2)
{2, 3}
同时存在于集合A和集合B中的元素组成集合C,集合C中的元素既是A的元素,又是B的元素,并且A和B所有相同的元素都在C找到,那么C是A和B的交集
差集
>>> s1
{1, 2, 3}
>>> s2
{2, 3, 4}
>>> s1.difference(s2) 获取两个集合之间不同的元素,返回出来
{1}
>>> s1 = {1,2,3}
>>> s2 = {2,3,4}
>>> s1.difference_update(s2) 在difference基础上,原地修改
>>> s1
{1}
>>> s2
{2, 3, 4}
>>> s1
{1, 2, 3}
>>> s1 - s2 重载了difference方法,相当于s1.difference(s2)
{1}
集合A和B,当集合C的元素仅存在A中,但不存在B中,并且A中存在B中不存在的元素全部存在C中,那么C就是A和B的差集
对称差集
>>> s1 = {1,2,3}
>>> s2 = {2,3,4}
>>> s1.symmetric_difference(s2)
{1, 4}
对称差集,俩个集合中都不相同的元素,就是对称差集
>>> s1.symmetric_difference_update(s2)
>>> s1
{1, 4}
获取s1和s2的对称差集,返回赋值给s1,原地修改
>>> s1
{1, 2, 3}
>>> s2
{2, 3, 4}
>>> s1 ^ s2 重载了对称差集,相当于s1.symmetric_difference(s2)
{1, 4}
如果把两个集合A和B看成是一个全集,对称差集是交集的补集
并集
>>> s1
{1, 2, 3}
>>> s2
{2, 3, 4}
>>> s1.union(s2) 并集,将两个集合去重合并
{1, 2, 3, 4}
>>> s1
{1, 2, 3}
>>> s2
{2, 3, 4}
>>> s1.update(s2) 原地修改,将两个集合去重合并,并将返回值赋值给第一个集合
>>> s1
{1, 2, 3, 4}
>>> s1
{1, 2, 3}
>>> s2
{2, 3, 4}
>>> s1 |s2
{1, 2, 3, 4} set重载了按位或运算符,用于并集计算
集合的判断
子集,超集的概念
>>> s1 = {1,2,3,4}
>>> s2 = {2,3}
集合s1里的所有元素都能在集合B里找到,那么A是B的子集,B是A的超集
判断
>>> s2.issubset(s1) 判断s2是不是s1的子集
True
>>> s1.issubset(s2)
False
>>> s1.issuperset(s2) 判断s1是否是s2的超集
True
>>> s2.issuperset(s1)
False
>>> s1.issuperset(s1)
True
>>> s1.issubset(s1)
True
当两个元素相同的时候,那么他既是子集也是超集,因此都是True
>>> s1
{1, 2, 3, 4}
>>> s2
{2, 3}
>>> s1.isdisjoint(s2) 判断两个集合是否有交集,若是有交集则是false
False
>>> s3 = {1,2}
>>> s4 = {3,4}
>>> s3.isdisjoint(s4) 判断两个集合是否有交集,若是没有交集则是true
True
集合的限制
- list不能是集合的元素
- bytearray不能是集合的元素
- 集合不能是集合的元素