04-06 基本数据类型之集合类型及其内置方法

一、作用

  • 集合和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访问的类型,又称之为映射类型
posted @ 2020-03-14 23:56  给你加马桶唱疏通  阅读(167)  评论(0编辑  收藏  举报