关于集合
数学上,把set称做由不同的元素组成的集合,集合(set)的成员通常被称做集合元素。
集合有两种不同的类型,可变集合(set)和不可变集合(frozenset)。
对于可变集合,你可以添加和删除元素。对不可变集合则不允许这样做。
可变集合不是可hash的,不可变集合则正好相反,他们有hash值,下面我们会重点说一说可变集合。
可变集合有三大特性:无序、去重、可hash。
无序:集合既没有索引,也没有键,因此集合中的元素是随意摆放的。
去重:集合中的元素由于是可hash的,因此每个元素都是唯一的。
可hash:集合中的每个元素都可以利用hash()来查看它的hash值。hash值都是不可变的,不然你将无法找到它。
1.如何创建集合类型和给集合赋值
集合与列表和字典不同,没有特别的语法方法。只能用工厂方法set()和frozenset()进行创建。
>>> s = set('cheseshop') #可变集合 可直接用其他数据转化 >>> s {'c', 'p', 'h', 's', 'e', 'o'} >>> t = frozenset('bookshop') #不可变集合 >>> t frozenset({'p', 'h', 's', 'k', 'b', 'o'}) >>> type(s) <class 'set'> >>> type(t) <class 'frozenset'> >>> len(s) 6 >>> len(s) == len(t) #可以使用len()函数 True >>> s == t False
>>> set5 = {'kebi',True,[1,2,3,]} Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: unhashable type: 'list' #必须是可hash,也就是不可变的
2.如何访问集合中的值
集合不像之前学到过的序列可以通过索引来获取元素,也不像字典可以通过键来直接查询。
集合只能查看所有成员或者通过成员资格检测来查看。
>>> 'k' in s False >>> 'k' in t True >>> for i in s: ... print(i) ... c p h s e o >>> for i in t: ... print(i) ... p h s k b o
3.如何更新集合以及删除集合
add:添加单个成员
update:添加一组成员
remove:移除单个成员
pop:随机删除一个元素
clear:清空一个集合
>>> s.add('z') #添加单个 >>> s {'c', 'p', 'h', 's', 'z', 'e', 'o'} >>> s.add('xx') >>> s {'c', 'p', 'h', 's', 'z', 'e', 'xx', 'o'} >>> s.update('OMG') #添加多个 >>> s {'c', 'p', 'h', 's', 'z', 'e', 'M', 'xx', 'O', 'G', 'o'} >>> s.remove('xx') #移除单个 >>> s {'c', 'p', 'h', 's', 'z', 'e', 'M', 'O', 'G', 'o'} >>> s -=set('cphs') #移除多个 >>> s {'z', 'e', 'M', 'O', 'G', 'o'}
>>> s {'c', 'p', 'h', 's', 'e', 'o'} >>> s |=set('OMG') #与update等价 >>> s {'c', 'p', 'h', 's', 'e', 'M', 'O', 'G', 'o'}
>>> set1 {'kebi', 'maoxian', 'name'} >>> set1.pop() #随机删除一个元素,有返回值。 'kebi' >>> set1.pop() 'maoxian' >>> set1 {'name'}
>>> set1 {'kebi', 'name'} >>> set1.clear() #清空一个集合 >>> set1 set() >>> set1 {'kebi', 'maoxian', 'name'} >>> del set1 #删除一个集合 >>> set1 Traceback (most recent call last): File "<stdin>", line 1, in <module> NameError: name 'set1' is not defined
之前说过,只有可变集合可以修改
>>> t.add('z') Traceback (most recent call last): File "<stdin>", line 1, in <module> AttributeError: 'frozenset' object has no attribute 'add'
可以使用del来删除集合,当集合的引用计数变为0时,便会被标记随后被内存空间回收。
4.利用集合的特性去重
>>> tuple1 = ('SKT','KT','SKT','SSG','KT') #去除元祖中多余的 >>> set3 = set(tuple1) >>> set3 {'SSG', 'KT', 'SKT'} >>> list1 = [1,2,3,1,4,4,4,2] #去除列表中多余的 >>> set2 = set(list1) >>> set2 {1, 2, 3, 4} >>> list1 = list(set2) >>> list1 [1, 2, 3, 4]
>>> dict = {}.fromkeys(['kebi','maoxian'],'dasb') >>> dict {'kebi': 'dasb', 'maoxian': 'dasb'} >>> set(dict) 只能对键去重,值是可变的 {'kebi', 'maoxian'}
5.集合类型操作符
(1)成员资格检测:in 和 not in
>>> 'k' in s False >>> 'k' in t True
(2).集合等价\不等价:== 和 !=
两个集合相等是指:当且仅当其中一个集合中的每个成员同时也是另一个集合中的成员。
>>> s == t False >>> s != t True
(3).子集/超集
<或<=:判断子集
>或>=:判断超集
>>> set('shop') < set('cheeseshop') True >>> set('bookshop') >= set('shop') True >>> frozenset('shop') < set('cheeseshop') True >>> set('shop') < frosenset('cheeseshop') Traceback (most recent call last): File "<stdin>", line 1, in <module> NameError: name 'frosenset' is not defined >>> frozenset('shop') <= set('cheeseshop') True
注意:3中放宽了对等号的限制
(4)联合(|)
两个集合联合是一个新集合,该集合中的每个元素至少是其中一个集合的成员,与函数union()等价,生成的新的集合是可变集合
>>> s {'c', 'p', 'h', 's', 'e', 'o'} >>> t frozenset({'p', 'h', 's', 'k', 'b', 'o'}) >>> s.union(t) {'c', 'p', 'h', 's', 'k', 'e', 'b', 'o'}
>>> m =s | t #谁在前,集成谁 >>> type(m) <class 'set'>
(5)交集(&)
两个集合的交集是一个新集合,该集合中的每个元素同时需要是两个集合的成员,生成的集合为可变集合。
>>> s & t #谁在前继承谁 {'p', 'h', 'o', 's'} >>> s.intersection(t) {'p', 'h', 'o', 's'} >>> l = s.intersection(t) >>> type(l) <class 'set'> >>> k = t.intersection(s) #谁是主体,继承谁 >>> type(k) <class 'frozenset'>
(6).差补/相对补集 -
s - c 的差补就是s中有,c中没有的;同理,c - s的差补就是c中有而s中没有的,与函数difference()等价
>>> s {'c', 'p', 'h', 's', 'e', 'o'} >>> t frozenset({'p', 'h', 's', 'k', 'b', 'o'}) >>> s - t #谁是主体,继承谁的集合类型 {'c', 'e'} >>> t -s frozenset({'b', 'k'})
(7)对称差补 ^
对称差补是两个集合中的成员,但是不单独属于哪一个成员。就是s -c的差补加上c -s的差补。
>>> s ^ t {'c', 'b', 'k', 'e'} >>> w = s ^ t >>> type(w) <class 'set'> >>> q = t ^ s #谁在前,就继承谁 >>> type(q) <class 'frozenset'>
6.集合类型的内建方法
(1)适合于所有集合的方法(通用)
方法名称 | 操 作 |
s.issubset(t) | 如果s 是t 的子集,则返回True,否则返回False |
s.issuperset(t) | 如果t 是s 的超集,则返回True,否则返回False |
s.union(t) | 返回一个新集合,该集合是s 和t 的并集 |
s.intersection(t) | 返回一个新集合,该集合是s 和t 的交集 |
s.difference(t) | 返回一个新集合,该集合是s 的成员,但不是t 的成员 |
s.symmetric_difference(t) | 返回一个新集合,该集合是s 或t 的成员,但不是s 和t 共有的成员 |
s.copy() | 返回一个新集合,它是集合s 的浅复制 |
(2)仅适合可变集合
方法名 | 操 作 |
s.update(t) | 用t 中的元素修改s, 即,s 现在包含s 或t 的成员 |
s.intersection_update(t) | s中的成员是共同属于s 和t 的元素 |
s.difference_update(t) | s中的成员是属于s 但不包含在t 中的元素 |
s.symmetric_difference_update(t) | s中的成员更新为那些包含在s 或t 中,但不 是s和t 共有的元素 |
s.add(obj) | 在集合s 中添加对象obj |
s.remove(obj) | 从集合s 中删除对象obj;如果obj 不是集合s 中的元素(obj notin s),将引发KeyError 错误 |
s.discard(obj) | 如果obj 是集合s 中的元素,从集合s 中删除对象obj |
s.pop() | 删除集合s 中的任意一个对象,并返回它 |
s.clear() | 删除集合s 中的所有元素 |