关于集合

数学上,把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 中的所有元素
posted @ 2017-10-24 00:05  明王不动心  阅读(236)  评论(0编辑  收藏  举报