素数、杨辉三角、封装结构和集合操作(16)——集合及操作
集set
可变的、无序的、不重复的元素的集合
set定义
s1=set() ##定义空set type(s1) set s2={} ##不是set而是字典 type(s2) dict s3={1,2,3} ##非空set可以用此写法定义 type(s3) set s4={'a':1,'b':2} ##字典需要键对定义 type(s4) dict s5=set(range(5)) s5 {0, 1, 2, 3, 4} s6={'abc',2,3,3,'abc',(1,2,3),(2,3),(2,3)} ##set元素无法重复,set是比较元素的hash值 s6 {(1, 2, 3), (2, 3), 2, 3, 'abc'} s6[1:] ##set是无序集合,没有索引概念,无法支持索引切片 --------------------------------------------------------------------------- TypeError Traceback (most recent call last) <ipython-input-46-c11924d6da50> in <module> ----> 1 s6[1:] TypeError: 'set' object is not subscriptable list(s6) [2, 3, 'abc', (1, 2, 3), (2, 3)] list(s6)[1:] ##可以以列表方式切片 [3, 'abc', (1, 2, 3), (2, 3)] s7={1,'abc',(1,2),[],(1,[2,3]),None,True} ##set不支持不可hash类型或嵌套不可hash类型的元素,大部分可变序列都为不可hash类型 --------------------------------------------------------------------------- TypeError Traceback (most recent call last) <ipython-input-52-15199fdfbfbe> in <module> ----> 1 s7={1,'abc',(1,2),[],(1,[2,3]),None,True} TypeError: unhashable type: 'list' hash([],bytearray(),{},{1}) --------------------------------------------------------------------------- TypeError Traceback (most recent call last) <ipython-input-54-5a006b60c685> in <module> ----> 1 hash([],bytearray(),{},{1}) TypeError: hash() takes exactly one argument (4 given)
set的元素
set的元素要求必须可以hash
元素不可以使用索引
set可以迭代
set增加
增加一个元素到set中
如果元素存在,什么都不做
s8={1,2,3,'abc',(1,2)} s8 {(1, 2), 1, 2, 3, 'abc'} s8.add(7) s8 {(1, 2), 1, 2, 3, 7, 'abc'} s8.add(1,7) ##一次只能增加一个元素 --------------------------------------------------------------------------- TypeError Traceback (most recent call last) <ipython-input-62-e56046ecd9ae> in <module> ----> 1 s8.add(1,7) TypeError: add() takes exactly one argument (2 given) s8.add(7) ##加入已存在元素自动去重 s8 {(1, 2), 1, 2, 3, 7, 'abc'}
update(*others)
合并其它元素到set集合中来
参数others必须是可迭代对象
就地修过
s8.update(range(10)) s8 {(1, 2), 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 'abc'} s8.update(range(10),range(15)) s8 {(1, 2), 0, 1, 10, 11, 12, 13, 14, 2, 3, 4, 5, 6, 7, 8, 9, 'abc'}
set删除
remove(elem)
从set中移除一个元素
元素不存在,抛出keyError异常
s8.remove(13) s8 {(1, 2), 0, 1, 10, 11, 12, 14, 2, 3, 4, 5, 6, 7, 8, 9, 'abc'} s8.remove(0,1,10) --------------------------------------------------------------------------- TypeError Traceback (most recent call last) <ipython-input-67-90be107bcb1b> in <module> ----> 1 s8.remove(0,1,10) TypeError: remove() takes exactly one argument (3 given) s8.remove(15) --------------------------------------------------------------------------- KeyError Traceback (most recent call last) <ipython-input-69-b2ea987852af> in <module> ----> 1 s8.remove(15) KeyError: 15
discard(elem)
从set中移除一个元素
元素不存在,什么都不做
s8.discard(15)
pop()
移除并返回任意的元素
空集返回keyError异常
s8.pop() (1, 2) s8 {0, 1, 10, 11, 12, 14, 2, 3, 4, 5, 6, 7, 8, 9, 'abc'} s8.pop() 1 s8 {0, 10, 11, 12, 14, 2, 3, 4, 5, 6, 7, 8, 9, 'abc'}
clear()
移除所有元素
s8.clear()
s8
set()
set修改,查询
修改
先删除再加入
查询
非线性结构,无法索引
遍历
可以迭代所有元素
成员运算符
in和not in判断元素是否在set中
set成员运算符效率比较
n1=100 n2=10000000 l1=list(range(n1)) l2=list(range(n2)) s1=set(range(n1)) s2=set(range(n2)) %timeit (-1 in l1) 2.16 µs ± 77.3 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each) %timeit (-1 in l2) 220 ms ± 7.49 ms per loop (mean ± std. dev. of 7 runs, 1 loop each) %timeit (-1 in s1) 66.4 ns ± 0.68 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each) %timeit (-1 in s2) 68.1 ns ± 1.25 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)
set和线性结构
线性结果的查询时间复杂度是O(n),随着数据规模增大而增加耗时
set,dict等结构,内部使用hash值作为key,时间复杂度可以做到O(1),查询时间和数据规模无关
可hash(不可变类型,是可哈希类型,hashable)
数值型int、float、complex
布尔型True、False
字符串string、bytes
tuple
None
集合
基本概念
全集
所有元素的集合,例如实数集,所有实数组成的集合就是全集
子集subset和超集superset
一个集合A所有元素都在另一个集合B内,A是B的子集,B是A的超集
真子集和真超集
A是B的子集,且A不等于B,A就是B的真子集,B是A的真超集
并集
多个集合合并的结果
交集
多个集合的公共部分
差集
集合中除去和其他集合公共部分
集合运算
并集
将两个集合A和B的所有的元素合并到一起,组成的集合称作集合A与集合B的并集
union(*others)
返回和多个集合合并后的新的集合
|运算符重载,等同union
update(*others)
和多个集合合并,就地修改
|=,等同update
交集
集合A和B,由所有属于A且属于B的元素组成的集合
intersection(*others)
返回和多个集合的交集
&,等同intersection
intersection_update(*others)
获取和多个集合的交集,冰就地修改
&=,等同intersection_update
差集
集合A和B,由所有属于A且不属于B的元素组成的集合
difference(*others)
返回和多个集合的差集
-,等同difference
difference_update(*others)
获取和多个集合的差集并就地修改
-=,等同difference_update
对称差集
集合A和B,由所有不属于A和B的交集元素组成的集合,记作(A-B)U(B-A)
symmetric_differece(other)
返回和另一个集合的差集
^,等同symmetric_differece
symmetric_differece_update(other)
获取和另一个集合的差集并就地修改
^=,等同于symmetric_differece_update
issubset(other)、<=
判断当前集合是否是另一个集合的子集
set1<set2
判断set1是否是set2的真子集
issuperset(other)、>=
判断当前集合是否是other的超集
set1>set2
判断当前集合是否是other的超集
isdisjoint(other)
当前集合和另一个集合没有交集
没有交集,返回True
集合应用
1.共同好友
你的好友A、B、C,他的好友C、B、D,求共同好友
{'A','B','C'}.intersection({'B','C','D'}) {'B', 'C'}
2.微信群提醒
XXX与群里其他人都不是微信朋友关系
3.权限判断
有一个API,要求权限同时具备A、B、C才能访问,用户权限是B、C、D,判断用户是否能够访问该API
有一个API,要求权限具备A、B、C任意一项就可访问,用户权限是B、C、D,判断用户是否能够访问该API
4.一个总任务列表,存储所有任务,一个完成的任务列表,找出未完成的任务
业务中,任务ID一般不可以重复
所有任务ID放到一个set中,假设为ALL
所有已完成的任务ID放到一个set中,假设为COMPLETED,它是ALL的子集
ALL-COMPLETED=UNCOMPLETED
5.随机产生2组各10个数字的列表,如下要求:
每个数字取值范围1-10
a=[1,9,7,5,6,7,8,8,2,6] b=[1,9,0,5,6,4,8,3,2,3] s1=set(a) s2=set(b) s1 {1, 2, 5, 6, 7, 8, 9} s2 {0, 1, 2, 3, 4, 5, 6, 8, 9}
统计20个数字中,一共有多少个不同的数字?
s1|s2
{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
2组之间进行比较,不同的数字有几个?分别是什么?
s1^s2
{0, 3, 4, 7}
2组之间进行比较,相同的数字有几个?分别是什么?
s1&s2
{1, 2, 5, 6, 8, 9}