07基本数据类型---集合
唯一的、不可变对象的无序集合,支持与数学集合理论相对应的操作
集合的操作很像一个无值的字典
由于集合是无序的,并且不会把键匹配到值,因此,集合既不是序列也不是映射类型,它们是自成一体的类型
由于是无序的,因此不支持索引和切片这样的操作
集合只能包含不可变(即可散列的)的对象类型,因此,字典和列表不能嵌入到集合中,集合也不能嵌入到集合中,但是元组是可以嵌入的
集合是可迭代容器,支持len(),for循环和列表解析这样的操作
1、集合的创建
x = set((1,2,3)) #接收一个序列或可迭代对象 y = set() #创建空集合必须这样创建 z = {1,2,3}
2、支持一般的数学集合运算
x = set('abcde') # {'a', 'e', 'c', 'b', 'd'} print('a' in x) # True print(x - y) # {'b', 'e', 'd'} print(x.add('m')) # None print(x) # {'a', 'd', 'm', 'c', 'e', 'b'} x.add((1,)) # 可以添加元组 x.add([1]) #会报错,TypeError: unhashable type: 'list',字典和列表不能嵌入到集合中 print(x.remove('a')) # None print(x) # {'d', 'c', 'b', 'e', 'm'}
3、集合解析
x = {i**2 for i in [1,2,3,4]} #{16, 1, 4, 9}
4、集合应用
# 1.可以用来把一些重复项从其他集合中过滤掉
# 2.当遍历图或环结构时,可以记录已访问过的位置
# 3.处理较大的数据集合时,两个集合的交集包含了两个领域的共同对象,并集包含了所有的项目。
练习1:关系运算
有如下两个集合,pythons是报名python课程的学员名字集合,linuxs是报名linux课程的学员名字集合
pythons={'alex','egon','yuanhao','wupeiqi','gangdan','biubiu'}
linuxs={'wupeiqi','oldboy','gangdan'}
1. 求出既报名python又报名linux课程的学员名字集合
2. 求出所有报名的学生名字集合
3. 求出只报名python课程的学员名字
4. 求出没有同时这两门课程的学员名字集合
pythons = {'alex','egon','cc','dd','biubiu'} linuxs = {'egon','cc'} python_and_linux = pythons & linuxs python_or_linux = pythons | linuxs python_only = pythons - linuxs one_only = pythons ^ linuxs #^对称差集:返回两个集合中不重复的元素 print(one_only)
练习2:去重
1. 有列表l=['a','b',1,'a','a'],列表元素均为可hash类型,去重,得到新列表,
且新列表无需保持列表原来的顺序
2.在上题的基础上,保存列表原来的顺序
3.去除文件中重复的行,肯定要保持文件内容的顺序不变
4.有如下列表,列表元素为不可hash类型,去重,得到新列表,且新列表一定要保持列表原来的顺序
l=[
{'name':'egon','age':18,'sex':'male'},
{'name':'alex','age':73,'sex':'male'},
{'name':'egon','age':20,'sex':'female'},
{'name':'egon','age':18,'sex':'male'},
{'name':'egon','age':18,'sex':'male'},
]
# 1.新列表无需保持列表原来的顺序 l=['a','b',1,'a','a'] l = list(set(l)) print(l) #[1, 'a', 'b'] # 2.保存列表原来的顺序 # 方法1:不利用集合 l=['a','b',1,'a','a'] new_l = [] for i in l: if i not in new_l: new_l.append(i) print(new_l) # 方法2:利用集合 l=['a','b',1,'a','a'] s = set() new_l = [] for i in l: if i not in s: #利用集合判断是否是重复的元素,如果不是重复的则在下面的列表里进行添加 s.add(i) new_l.append(i) #注意这里是new_l添加元素 print(new_l) # 方法3:利用集合+列表排序 l=['a','b',1,'a','a'] new_l = list(set(l)) #此时改变了顺序 new_l.sort(key=l.index) #将list2中的元素按照list1中元素出现的顺序排序 print(new_l)
3.去除文件中重复的行,肯定要保持文件内容的顺序不变
new_lines = [] with open('set_file.txt', 'r') as f_read,open('set_file.txt', 'w') as f_write: lines = f_read.readlines() for line in lines: if line not in new_lines: new_lines.append(line) for line in new_lines: f_write.write(line)
4.有如下列表,列表元素为不可hash类型,去重,得到新列表,且新列表一定要保持列表原来的顺序
#集合元素必须是不可变类型,字典是可变元素
l = [ {'name': 'egon', 'age': 18, 'sex': 'male'}, {'name': 'alex', 'age': 73, 'sex': 'male'}, {'name': 'egon', 'age': 20, 'sex': 'female'}, {'name': 'egon', 'age': 18, 'sex': 'male'}, {'name': 'egon', 'age': 18, 'sex': 'male'}, ] # (1)方法1:将字典元素转变为元组添加到set中 s = set() new_l = [] for i in l: # 集合不可添加字典元素,先将其转变为元组 val = (i['name'],i['age'],i['sex']) if val not in s: s.add(val) # 这里自己开始写的是new_l.append(val),等到的结果是列表里元组 # new_l.append(val) new_l.append(i) print(new_l) #(2)方法2:定义函数,既可以针对可以hash类型又可以针对不可hash类型 def func(items, key=None): s = set() for item in items: # 这里Key(item)就是得到字典中的值,传入的key是一个Lambda定义的函数,根据Key返回value val = item if key is None else key(item) #和方法1思想一样,也是转换为元组 if val not in s: s.add(val) yield item new_l = list(func(l,key=lambda dic:(dic['name'],dic['age'],dic['sex']))) print(new_l)