一、作用
- 集合和list,tuple、dict一样都可以存放多个值,但是集合的主要作用是:关系运算、去重
friends1 = ["zero", "kevin", "jason", "egon"]
friends2 = ["Jy", "ricky", "jason", "egon"]
# 需求:取出friends1与friends2中他们相同的朋友(下面这种方式去重太繁琐了,所以我们接下来使用集合的特性去重)
li = []
for i in friends1:
if i not in friends2:
li.append(i)
print(li) # ['zero', 'kevin']
二、定义
- 前提补充:不可哈希 == 可变类型、可哈希 == 不可变类型
- 定义:在{}内,用逗号分隔开多个元素,多个元素必须满足以下三个条件:
- 1、集合内元素必须为不可变类型。
- 2、集合内元素是无序的。
- 3、集合内元素没有重复,如果有重复的且只留一个。(达到去重效果)
# 1、验证:集合内元素必须为不可变类型
s = {1, 2.2, 'aaa', True, None, (1, 2, 3)}
# s1 = {[1, 2, 3], 'aa'} # TypeError: unhashable type: 'list'(类型错误:不可刷新的类型:'list')
# 2、验证:集合内元素是无序的
s1 = {1, 'a', 2, 'b', 3, 'c'}
print(s1) # {1, 2, 3, 'b', 'c', 'a'}
# 3、验证:集合内元素没有重复,如果有重复的且只留一个。(达到去重效果)
s2 = {1, 1, 1, 1, 'a', 2, 'b', 3, 'c'}
print(s2) # {'b', 1, 2, 3, 'c', 'a'}
# 4、定义空集合 与 定义空字典区分
# 定义空集合
s = set()
print(s, type(s)) # set() <class 'set'>
print(bool(s)) # False
# 定义空字典
dic = {}
print(dic, type(dic)) # {} <class 'dict'>
print(bool(dic)) # False
三、类型转换
- 只可以转换不可变类型:整型、浮点型、字符串、元组、字典的key
- 注意:虽然字典是可变类型,但是这里的转换只是争对key的转换,我们知道字典的key是不可变类型,它会把key进行转换,默认转换的也就是key。
# 1、整型转换成集合
# res = set({1, 2, 3, 4})
res = {1, 2, 3, 4}
print(res, type(res)) # {1, 2, 3, 4} <class 'set'>
# 2、浮点型转换成集合
# res1 = set({1.1, 2.2, 3.3, 4.4})
res = {1.1, 2.2, 3.3, 4.4}
print(res, type(res)) # {1.1, 2.2, 3.3, 4.4} <class 'set'>
# 3、字符串转换成集合
# res = set({'a', 'b', 'c', 'd', ' ', 'a', 'b', 'c', 'd'})
# res = {'a', 'b', 'c', 'd', ' ', 'a', 'b', 'c', 'd'}
res = set('abcd abcd')
print(res, type(res)) # {'b', ' ', 'a', 'd', 'c'} <class 'set'>
# 4、元组转换成集合
res = set((1, 2, 3, (1, 2, 3)))
print(res, type(res)) # {1, 2, 3, (1, 2, 3)} <class 'set'>
# 5、字典转换成集合(可以理解为遍历这个集合,拿到字典的key,因为字典key是不可变得,所以可以进行转换,而下面注意)
res = set({'name': 'egon', 'age': 18})
print(res, type(res)) # {'name', 'age'} <class 'set'>
# 6、整型、浮点型、字符串、元组、字典综合转换成集合
res = set(('aaa', 1.2, 111, (1, 2, 3)))
print(res) # {'aaa', 1.2, (1, 2, 3), 111}
# 注意: 只要里面存在可变类型就不能够转换成集合(可变: 字典)
# res = set(({'name': 'egon'}, 'aaa', 1.2, 111, (1, 2, 3))) # TypeError: unhashable type: 'dict'
四、使用:内置方法
👇关系运算👇
1、交集:& 与 intersection
friends1 = {"zero", "kevin", "jason", "egon"}
friends2 = {"Jy", "ricky", "jason", "egon"}
# 需求:求两个用户共同的好友
print(friends1.intersection(friends2)) # {'egon', 'jason'}
print(friends1 & friends2) # (推荐){'egon', 'jason'}
2、并集:| 与 union
friends1 = {"zero", "kevin", "jason", "egon"}
friends2 = {"Jy", "ricky", "jason", "egon"}
# 需求:求两个用户所有的好友
print(friends1.union(friends2)) # {'jason', 'kevin', 'egon', 'zero', 'Jy', 'ricky'}
print(friends1 | friends2) # (推荐){'jason', 'kevin', 'egon', 'zero', 'Jy', 'ricky'}
3、差集:- 与 difference
friends1 = {"zero", "kevin", "jason", "egon"}
friends2 = {"Jy", "ricky", "jason", "egon"}
# 需求:求friends1有的好友而friends2没有好友
print(friends1.difference(friends2)) # {'kevin', 'zero'}
print(friends1 - friends2) # (推荐){'zero', 'kevin'}
# 需求:求friends2有的好友而friends1没有好友
print(friends2.difference(friends1)) # {'Jy', 'ricky'}
print(friends2 - friends1) # (推荐){'Jy', 'ricky'}
4、对称差集:^ 与 symmetric_difference
friends1 = {"zero", "kevin", "jason", "egon"}
friends2 = {"Jy", "ricky", "jason", "egon"}
# 需求:求两个用户共同的好友
print((friends2 - friends1) ^ (friends1 - friends2)) # {'Jy', 'zero', 'ricky', 'kevin'}
print(friends1.symmetric_difference(friends2)) # {'Jy', 'zero', 'kevin', 'ricky'}
print(friends1 ^ friends2) # (推荐) {'Jy', 'zero', 'kevin', 'ricky'}
5、父子集(完全包含关系,包括两者相等):比较运算符 与 issuperset 与 issubset
- s > s1 等同于 s.issuperset(s1) 等同于 s1.issubset(s)
- s > s1 判断s是否完全包含s1
- s.issuperset(s1) 判断s是不是s1的父集,也就是判断s是不是完全包含s1
- s1.issubset(s) 判断s1是不是s的子集,也就是判断s1是不在完全在s中
- s == s1 s与s1互为父子集合关系,也就是说s1与s中元素一样。
# 没有父子包含关系
s = {1, 2, 3}
s1 = {1, 4}
# s > s1 等同于 s.issuperset(s1)
print(s > s1) # False
print(s.issuperset(s1)) # False
# 父子包含关系
s = {1, 2, 3}
s1 = {1, 2}
# s > s1 等同于 s.issuperset(s1) 等同于 s1.issubset(s)
print(s > s1) # 判断s是不是完全包含s1, True
print(s.issuperset(s1)) # True
print(s1.issubset(s)) # True
print(s < s1) # False
# 互为父子关系
s = {1, 2}
s1 = {1, 2}
# s == s1 等同于 s.issuperset(s1)
print(s == s1) # s与s1的互相之间的包含关系,互为父子,True
print(s.issuperset(s1)) # True
print(s > s1) # False
print(s1 > s) # False
👇去重👇
1、只能争对不可变类型去重,且去重以后无法保证原来的(如果你想去重多值类型,必须保证该多值类型中的元素是不可变的类型)
# 注意:去重不可变类型以后,不能保证原有数据的顺序。
print(set({1, 1, 1, 2, 2, 'a', 'a', 2.2, 2.2})) # {1, 2, 2.2, 'a'}
print({1, 1, 1, 2, 2, 'a', 'a', 2.2, 2.2}) # (推荐) {1, 2, 2.2, 'a'}
li = [1, 'a', 'b', 'z', 1, 1, 1, 2]
print(list(set(li))) # [1, 2, 'a', 'b', 'z']
# 举例:需求,去重列表中重复的字典
# 注意:列表中元素(字典)是可变类型,这个时候你就不能使用集合去重。
li = [
{'name': 'lili', 'age': 18, 'sex': 'male'},
{'name': 'jack', 'age': 73, 'sex': 'male'},
{'name': 'tom', 'age': 20, 'sex': 'female'},
{'name': 'lili', 'age': 18, 'sex': 'male'},
{'name': 'lili', 'age': 18, 'sex': 'male'},
]
new_li = []
for item in li:
if item not in new_li:
new_li.append(item)
li = new_li
print(li)
'''
[
{'name': 'lili', 'age': 18, 'sex': 'male'},
{'name': 'jack', 'age': 73, 'sex': 'male'},
{'name': 'tom', 'age': 20, 'sex': 'female'}
]
'''
👇其它操作👇
1、长度len
s = {'jason', 'kevin', 'egon', 'zero', 'Jy', 'ricky'}
print(len(s)) # 6
2、成员运算in 和 not in
s = {'jason', 'kevin', 'egon', 'zero', 'Jy', 'ricky'}
print('jason' in s) # True
print('jason' not in s) # (推荐), False
print(not 'jason' in s) # False
3、循环
- 强调:集合是无序的,所以集合使用for循环遍历取值,取出来的值的下顺序也是无序的。
s = {'jason', 'kevin', 'egon', 'zero', 'Jy', 'ricky'}
for item in s:
print(item)
'''
Jy
egon
zero
jason
ricky
kevin
'''
👇其它内置方法之需要掌握的操作👇
1、删除 discard 与 remove 区分
- discard 删除元素不存在,什么也不做。只传一个值,该值是任意类型的元素。(推荐使用)
- remove 删除元素不存在,报错。只传一个值,该值是任意类型的元素。
s = {'a', 1, 'c', 4, 'ddd'}
# 1、使用discard(推荐使用)
# discard默认没有返回值,python为了防止报错,特地会追加一个None充当返回值
res = s.discard(4)
print(res) # None
s.discard('a')
s.discard("1")
print(s) # {1, 'c', 'ddd'}
# 2、使用remove
s.remove(1)
print(s) # {'ddd', 'c'}
# 3、discard 与 remove 区分
# discard删除不存在的元素,不会报错
s.discard('5555')
# remove删除不存在的元素,会报错
# s.remove('55555') # KeyError: '55555'
2、更新 update
- update 新集合更新老集合。你操作的集合中有则不添加,无则作为更新的内容添加到里面去。
s = {'wangmao', 'alex', 'egon'}
s.update({'EGON', 'ALEX'})
print(s) # {'wangmao', 'alex', 'EGON', 'ALEX', 'egon'}
s.update({'WANGMAO'})
print(s) # {'wangmao', 'alex', 'EGON', 'ALEX', 'egon', 'WANGMAO'}
4、添加 add
- add 单独添加某一个元素。(注意:只能单个添加,如果想多个添加,使用update方法)
s = {'wangmao', 'alex', 'egon'}
s.add('ALEX')
print(s) # {'alex', 'egon', 'wangmao', 'ALEX'}
s.add('EGON')
print(s) # {'ALEX', 'wangmao', 'egon', 'EGON', 'alex'}
👇其它内置方法之需要了解的操作👇
3、删除 pop
- pop 不指定参数,随机删除集合中任意元素。
- 集合的pop与字典、列表不同点:列表中的pop不指定删除末尾,且只能指定对应位置的索引。字典必须要指定值,且这个值是key。
- 集合的pop与字典、列表相同点:它们都有返回值。
s = {'wangmao', 'alex', 'egon'}
res = s.pop()
print(res) # wangmao
print(s) # {'egon', 'alex'}
5、isdisjoint
- isdisjoint 判断两个集合是否没有交集,完全互相独立。
s = {1, 2, 3}
s1 = [4, 5, 6]
print(s.isdisjoint(s1)) # True
7、difference_update
- difference_update 从这个集合中删除另一个集合的所有元素,也就是说你定义的集合中的元素,如果有和你操作的集合中有重复的,那么就会删除你操作的集合,如果没有则不删除。
s = {'wangmao', 'alex', 'egon'}
s.difference_update({'alex', "EGON"})
print(s) # {'wangmao', 'egon'}
总结与分类:数字类型、字符串、列表、元组、字典、集合
- 有序、无序:判断条件是否有索引,有索引就是有序。
- 有序:字符串、元组、列表
- 无序:数字、集合、字典(字典又称为映射类型。字典的在python3中做了优化,让你看起来是有序的,其实是无序的)
- 存一个值,存多个值:存一个值称之为标量或原子类型,存多个值称之为容类型
- 存一个值:数字、字符串
- 存多个值:列表、元组、字典
- 可变,不可变
- 可变: 列表、字典、集合
- 不可变:数字、字符串、元组(元组的不可变指的是元组内索引对应值的内存地址不可以被改变)
- 访问方式
- 直接访问:数字
- 顺序访问:字符串、列表、元组
- key访问: 字典(可以用key访问的类型,又称之为映射类型)