3.6 集合及相关操作
1.创建集合
集合(set)是一个无序的不重复元素序列,集合元素也称为集合成员。集合中的元素没有重复,且没有顺序,也没有下标。
我们可以使用大括号“{}”或者set()函数创建集合。注意:因为“{}”可用来创建一个空字典,因此创建一个空集合必须用set()函数,不能用“{}”。
创建集合格式:
var= set(x)
如果不提供任何参数,则默认会生成空集合。如果提供一个参数x,则该参数x必须是可迭代的,即一个序列,或迭代器,或支持迭代的一个对象。例如,一个列表或一个字典。
见示例3-52。
a=set('alacazam') print('a= ', a)
程序运行结果:
a= {'m', 'l', 'a', 'z', 'c'}
类似于列表推导式,同样,集合也支持集合推导式。见示例3-53。
b = {x for x in 'abracadabra' if x not in 'abc'} print('b= ', b)
程序运行结果:
b= {'r', 'd'}
2.增加集合元素
增加单个集合元素可以使用add(x)方法,其中参数x是一个元素值。
格式:
sets.add(x)
sets表示一个字典。在上述操作中,如果元素已存在,则不进行任何操作。
添加多个集合元素可以使用update(x)方法,其中参数x可以是集合、列表、元组、字典等。
格式:
sets.update(x)
见示例3-54。
a=set('alacazam') print('a= ', a) a.add(10) a.add(20) print('a= ', a) a.update({'x', 'r', 'z'}) print('a= ', a)
程序运行结果:
a= {'m', 'l', 'a', 'z', 'c'} a= {'m', 'l', 10, 'a', 'z', 20, 'c'} a= {'r', 'm', 'l', 10, 'a', 'x', 'z', 20, 'c'}
3.删除集合元素
删除集合元素可以使用remove(x)方法,其中x是一个元素值。
格式:
sets.remove(x)
将元素x从集合sets中删除,如果元素不存在,则会发生错误。
此外,还有一个方法也能移除集合中的元素,且如果元素不存在,也不会发生错误。
格式:
sets.discard(x)
因为集合中的元素没有顺序,所以也可以用pop()函数随机删除集合中的一个元素。一般会删除显示顺序的第一个元素,并返回删除掉的元素值。
格式:
var=sets.pop()
见示例3-55。
#删除集合元素 b={1,2,3,5} b.discard(2) print(’删除b中元素2: ', b) b.discard(2) print(’删除b中元素2(没有报错): ', b) b.remove(3) print(’删除b中元素3: ', b) #弹出一个集合元素 d=b.pop() print(’弹出一个集合元素:', d, ' b= ', b)
程序运行结果:
删除b中元素2: {1, 3, 5} 删除b中元素2(没有报错): {1, 3, 5} 删除b中元素3: {1, 5} 弹出一个集合元素: 1 b= {5}
4.集合复制
集合是对象数据,而对象数据不能通过变量来直接赋值。例如,假设b是集合,e=b,则id(e)和id(b)的地址相同。如果修改集合e,则集合b的数据也随之发生变化,因为集合e和集合b是同一份数据。
集合复制要用copy()方法。
格式:
var=sets.copy()
此时,集合var和集合sets的地址不同,即id(var)和id(sets)不相同。此时如果修改集合var,则集合sets的数据不会发生变化,因为集合var和集合sets是不同的数据。
见示例3-56。
a=set('alacazam') b=a c=a.copy() b.add(999) print('a= ', a) print('c= ', c)
程序运行结果:
a= {999, 'm', 'l', 'a', 'z', 'c'} c= {'z', 'm', 'l', 'c', 'a'}
5.不可变集合
有时为了防止程序意外修改集合数据,可以使用冰冻函数即使用frozenset()函数返回一个不可变的集合备份。我们只能访问,不能修改不可变的集合中的元素。set()函数和frozenset()函数可以分别用来生成可变的集合和不可变的集合。
格式:
var= frozenset(x)
如果想解冻集合就可以使用集合的set()函数。见示例3-57。
bb = {x for x in range(1,5)} var = frozenset(bb) print(var, type(var)) var2 = set(var) print(var2, type(var2))
程序运行结果:
frozenset({1, 2, 3, 4})<class 'frozenset'> {1, 2, 3, 4} <class 'set'>
6.集合元素个数
格式:
var=len(sets)
返回集合sets元素的个数。
见示例3-58。
bb = {x for x in range(1,5)} print('bb= ', bb) print('len(bb)=', len(bb))
程序运行结果:
bb= {1, 2, 3, 4} len(bb)= 4
7.清空集合
格式:
sets.clear()
相关演示见示例3-59。
""" 集合 """ bb = {x for x in range(1,5)} var = frozenset(bb) print(var, type(var)) var2 = set(var) print(var2, type(var2)) print() #可以使用大括号{ }或者set()函数创建集合 a=set('alacazam') print('a= ', a) #集合支持集合推导式 b = {x for x in 'abracadabra' if x not in 'abc'} print('b= ', b) #增加单个集合元素用app(x)函数,其中参数x是一个元素值 b.add('abc') print(’增加abc :b= ', b) #添加多个集合元素用update(x)函数,其中参数x可以是集合、列表、元组、字典等 c={1,2,3} b.update(c) print(’增加c={1,2,3} :b= ', b) #删除集合元素 b.discard(2) print(’删除b中元素2: ', b) b.discard(2) print(’删除b中元素2(没有报错): ', b) b.remove(3) print(’删除b中元素3: ', b) #弹出一个集合元素 d=b.pop() print(’弹出一个集合元素:', d, ' b= ', b) #集合复制 e=b #把b的地址复制给了e e.add('xyz') print('e=b e.add(\'xyz\') b= ', b) print('id(b)=', id(b), 'id(e)=', id(e), ' 地址相同’) f=b.copy() print('f=d.copy() f= ', f) print('id(b)=', id(b), 'id(f)=', id(f), ' 地址不相同’) #清空集合 b.clear() print(’清空集合b= ', b)
程序运行结果:
a= {'a', 'l', 'm', 'c', 'z'} b= {'r', 'd'} 增加abc :b= {'r', 'd', 'abc'} 增加c={1,2,3} :b= {1, 'd', 2, 3, 'abc', 'r'} 删除b中元素2: {1, 'd', 3, 'abc', 'r'} 删除b中元素2(没有报错): {1, 'd', 3, 'abc', 'r'} 删除b中元素3: {1, 'd', 'abc', 'r'} 弹出一个集合元素: 1 b= {'d', 'abc', 'r'} e=b e.add('xyz') b= {'d', 'abc', 'r', 'xyz'} id(b)= 42507400 id(e)= 42507400 地址相同 f=d.copy() f= {'r', 'd', 'xyz', 'abc'} id(b)= 42507400 id(f)= 156994024 地址不相同 清空集合b= set()
8.集合的相关操作
集合的基本功能包括关系测试和消除重复元素。集合对象还支持联合“union”、交集“intersection”、差集“difference”和对称差集“sysmmetric difference”等数学运算。
集合支持x in set, len(set)和for x in set等操作,这些操作同列表一样。作为一个无序的集合,其不记录元素的位置和插入点,因此,集合不支持索引下标等类似于列表的操作。
obj in s成员测试:如果obj是s中的一个元素则返回Ture,否则返回False。
obj not in s非成员测试:如果obj不是s中的一个元素则返回Ture,否则返回False。
t == s集合等价测试:测试集合s和集合t是否有相同的元素,如果有则返回Ture,否则返回False。
t ! = s集合不等价测试:与等价测试相反。
集合t和集合s支持一系列标准操作,包括并集、交集、差集和对称差集。例如:
a = t | s #t和s的并集 b = t & s #t和s的交集 c = t - s #求差集(项在t中,但不在s中) d = t ^ s #对称差集(项在t或s中,但不会同时出现在二者中)
9.集合相关函数和方法
集合相关函数和方法的种类及功能见表3-23。
表3-23 集合相关函数和方法
10.集合和列表转换
用set()函数可以把列表转换为集合,格式如下。
sets=set(lists)
用list()函数可以把集合转换为列表,格式如下。
lists=list(sets)
利用集合的无重复特性,我们可以将股票代码转化为集合,并能快速完成股票代码去重、股票代码池的合并、剔除股票黑名单等运算。见示例3-60。
#建立集合st1, st2 st1=set(['002027', '600061', '600080', '600659']) print('st1= ', st1) st2=set(['000001', '600061', '600088', '000002']) print('st2= ', st2) #集合中增加元素 print('\n----st1---- st1中增加600090') st1.add('600090') print(st1) print('\n----a = st1 | st2-----') #集合运算 a = st1 | st2 #st1和st2的并集 print(a) print('\n----b = st1 & st2-----') b = st1 & st2
#st1和st2的交集
print(b) print('\n----c = st1- st2-----') c = st1- st2 #求差集(项在st1中,但不在st2中) print(c) print('\n----d = st1 ^ st2-----') d = st1 ^ st2 #对称差集(项在st1或st2中,但不会同时出现在二者中) print(d) print('\n----st2 remove 600088-----') #集合元素删除 st2.discard('600088') print('st2 = ', st2) print('\n----集合转列表-----') st3=list(st2) print('st3 = ', st3) print('st2: ', type(st2), ' st3: ', type(st3))
程序运行结果:
st1= {'600080', '002027', '600659', '600061'} st2= {'600088', '000001', '000002', '600061'} ----st1---- st1中增加600090 {'600659', '600061', '600080', '002027', '600090'} ----a = st1 | st2----- {'600659', '600061', '600088', '000001', '600080', '002027', '600090', '000002'} ----b = st1 & st2----- {'600061'} ----c = st1- st2----- {'600080', '002027', '600659', '600090'} ----d = st1 ^ st2----- {'600659', '600088', '000001', '600080', '002027', '600090', '000002'} ----st2 remove 600088----- st2 = {'000001', '000002', '600061'} ----集合转列表----- st3 = ['000001', '000002', '600061'] st2: <class 'set'> st3: <class 'list'>