python集合(set)
1、集合set
约定:
set翻译为集合
collection翻译为集合类型,是一个大概念
set:
可变的、无序的、不重复的元素的集合
构造方法:
set() → new empty set object
set(iterable) → new set object
# -*- coding:utf-8 -*- # version:python3.7 s1 = set() # empty set s2 = {1,2,3} # set s3 = {} # dict:字典,not set s4 = set(range(5)) s5 = {'abc',1,1,2,2,3,3,'abc'} # set:去重 print(s1,type(s1)) print(s2,type(s2)) print(s3,type(s3)) print(s4) print(s5) 执行结果: set() <class 'set'> {1, 2, 3} <class 'set'> {} <class 'dict'> {0, 1, 2, 3, 4} {1, 2, 3, 'abc'}
set的元素要求必须可以hash
目前学过的不可hash的类型有list、set
# -*- coding:utf-8 -*- # version:python3.7 s1 = {1,2,'abc',(3,),[4]} print(s1) 执行结果:报错
TypeError s1 = {1,2,'abc',(3,),[4]} TypeError: unhashable type: 'list'
元素不可以使用索引
set可以迭代
2、set的增删改查
1>add(elem)
增加一个元素到set中
如果元素存在,什么都不做
2>update(*others)
合并其他元素到set集合中来
参数others必须是可迭代对象
就地修改
3>remove(elem)
从set中移除一个元素
元素不存在,抛出KeyError异常,Key:唯一
4>discard(elem)
从set中移除一个元素
元素不存在,什么都不做
5>pop() → item
移除并返回任意的元素
空集返回KeyError异常
6>clear()
移除所有元素
# -*- coding:utf-8 -*- # version:python3.7 s1 = {1,2,3} print(s1) s1.add(4) # 增加 print(s1) s1.update(range(6)) # 合并其他元素到该集合,并去重 print(s1) s1.remove(1) # 移除 print(s1) s1.discard(11) # 移除,元素不存在,什么都不做 print(s1) s1.pop() # 弹出 print(s1) 执行结果: {1, 2, 3} {1, 2, 3, 4} {0, 1, 2, 3, 4, 5} {0, 2, 3, 4, 5} {0, 2, 3, 4, 5} {2, 3, 4, 5}
修改
要么删除,要么加入新的元素,没有修改
查询
非线性结构,无法索引
遍历
可以迭代所有元素
成员运算符
in和not in判断元素是否在set中,效率呢?
在 IPython 中进行测试:
经测试,线性结构的查询时间复杂度是O(n),即随着数据规模的增大而增加耗时,set、dict等结构,内部使用hash值作为key,时间复杂度可以做到0(1),查询时间和数据规模无关
可hash
数值型int、float、 complex
布尔型True、False
字符串string、bytes
tuple
None
以上都是不可变类型,是可哈希类型,hashable
set的元素必修都是可hash的
3、集合基本概念
1>全集
所有元素的集合,例如实数集,所有实数组成的集合就是全集
2>子集subset和超集superset
一个集合A所有元素都在另一个集合B内,A是B的子集,B是A的超集
3>真子集和真超集
A是B的子集,且A不等于B,A就是B的真子集,B是A的真超集
4>并集:多个集合合并的结果
union(*others)
返回和多个集合合并后的新集合
| 运算符重载
等同union
update(*others)
和多个集合合并,就地修改
|=
等同update
5>交集:多个集合的公共部分
intersection(*others)
返回和多个集合的交集
&
等同于intersection
intersection_update(*others)
获取和多个集合的交集,并就地修改
&=
等同于intersection_update
6>差集:集合中除去和其他集合公共部分
difference(*others)
返回多个集合的差集
-
等同于difference
difference_update(*others)
获取和多个集合的差集并就地修改
-=
等同于difference_update
7>对称差集
集合A和B,由所有不属于A和B的交集元素组成的集合,记作(A-B)∪(B-A)
symmetric_differece(other)
返回和另一个集合的差集
^
等同symmetric_differece
symmetric_differece_update(other)
获取和另一个集合的差集并就地修改
^=
等同symmetric_differece_update
8>issubset(other)、<=
判断当前集合是否是另一一个集合的子集
set1 < set2
判断set1是否是set2的真子集
issuperset(other)、>=
判断当前集合是否是other的超集
set1 > set2
判断set1是否是set2的真超集
isdisjoint(other)
当前集合和另一个集合没有交集
没有交集,返回True
4、集合应用:
1>共同好友(交集运算)
你的好友A、B、C,他的好友C、B、D,求共同好友
2>微信群提醒
X与群里其他人都不是微信朋友关系!
并集:userid in (A | B | C ...) == False,A、B、C等是微信好友的并集,用户ID不在这个并集中,说明他和任何人都不是好友
群里所有其他人ids都不在X的朋友列表中T & ids == set()
3>权限判断
有一个API,要求权限同时具备A、B、C才能访问,用户权限是B、C、D,判断用户是否能够访问该API
API集合A,用户权限集合P。要用户权限全部包含API权限要求。
A-P= set(),A-P为空集,说明P包含A
A.issubset(P)也行,A是P的子集也行
A&P= A也行
有一个API,要求权限具备A、B、C任意一项就可访问,用户权限是B、C、D,判断用户是否能够访问该API
API集合A,权限集合P
A&P != set()就可以
A.isdisjoint(P) == False表示有交集
4>一个总任务列表,存储所有任务。一个完成的任务列表。找出为未完成的任务
业务中,任务ID一般不可以重复
所有任务ID放到一个set中,假设为ALL
所有已完成的任务ID放到一个set中,假设为COMPLETED,它是ALL的子集
ALL- COMPLETED = UNCOMPLETED
5>随机产生2组各10个数字的列表,如下要求:
每个数字取值范围[10,20]
统计20个数字中,一共有多少个不同的数字? #set()去重,求交集
2组之间进行比较,不同的数字有几个?分别是什么? #对称差集
2组之间进行比较,相同的数字有几个?分别是什么? #求交集
a=[1,9,7,5,6,7,8,8,2,6]
b=[1,9,0,5,6,4,8,3,2,3]