加入收藏 | 设为首页 | 会员中心 | 我要投稿 我爱制作网_沈阳站长网 (https://www.024zz.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 编程要点 > 语言 > 正文

详解Python集合Set,建 议珍藏!!

发布时间:2022-11-25 12:39:44 所属栏目:语言 来源:
导读:  大家好,我是Peter~
  
  在前面的几篇Python的文章中,我们介绍了Python的多种不同类型的对象:字符串、列表、元组、字典。它们有各自的特点:
  
  字符串str:存在索引,字符串中的元素是可以重

  大家好,我是Peter~
  
  在前面的几篇Python的文章中,我们介绍了Python的多种不同类型的对象:字符串、列表、元组、字典。它们有各自的特点:
  
  字符串str:存在索引,字符串中的元素是可以重复的,元素是不可变,不能修改的
  列表list:也能够进行索引和切片操作,元素可以修改,是可变的
  元组tuple:可以看成是不能进行修改的“列表”;元素不能直接修改,也可以进行索引和切片操作,类似列表
  字典:Python中十分常用,键值对组成,键必须是比可变的数据类型(比如元组),值可以是任意数据;字典是无序的
  如果说元组是列表和字符串的杂合体,那么集合可以看做是列表和字典的杂合体
  
  Python连载文章
  
  
  本文的整体目录结构:
  
  
  
  集合创建
  集合set的创建有两种方法:
  
  通过set函数创建,空集合只能用这种方式
  
  通过{}来创建
  
  空集合
  s1 = set()  # 空集合
  s1
  set()
  
  type(s1)
  set
  
  注意:空集合必须使用set函数来创建,因为{}是用来创建空字典的
  
  非空集合
  使用花括号创建
  
  s2 = {1,2,3,4}   
  s2
  {1, 2, 3, 4}
  
  type(s2)
  set
  
  使用set函数创建
  
  s3 = set([9,8,7,6])  # 将元素用列表装起来,set只能有一个参数
  s3
  {6, 7, 8, 9}
  
  type(s3)
  set
  
  s4 = set((11,22,33,44)) # 用元组装起来
  
  s4
  {11, 22, 33, 44}
  
  集合的元素不能重复
  
  集合中的元素是不能重复的;如果有重复的元素,集合会自动去重。这是一种非常高效的去重方式
  
  s5 = set([1, 2, 3, 4, 3, 2, 1]) # 存在重复数据
  
  s5
  {1, 2, 3, 4}
  产生的数据中自动将重复的去掉了
  
  type(s5) # 查看类型
  set
  
  s6 = set("javascript") # 字符串中a重复了,自动去重
  s6
  {'a', 'c', 'i', 'j', 'p', 'r', 's', 't', 'v'}
  
  特别点
  当我们创建集合的时候,需要注意数据类型
  
  s7 = {"python", [1,2,3,"java"], {"name":"xiaoming","age":19},100}
  
  s7
  TypeError                                 Traceback (most recent call last)
  
  <ipython-input-11-b8ed1637ec12> in <module>
  ----> 1 s7 = {"python", [1,2,3,"java"], {"name":"xiaoming","age":19},100}
        2 s7
  
  
  TypeError: unhashable type: 'list'
  上面报错中的关键词:unhashable,中文是不可哈希的。意思是创建的时候存在不可哈希的数据类型:列表 。我们可以记住:
  
  不可哈希,即代表可变,比如列表、字典等
  可哈希,即代表不可变,比如字符串,字典的键等
  当我们创建集合的时候,元素必须是可哈希的
  
  set集合方法
  首先我们通过dir(set)来查看集合的操作方法:
  
  print(dir(set))
  ['__and__', '__class__', '__contains__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__iand__', '__init__', '__init_subclass__', '__ior__', '__isub__', '__iter__', '__ixor__', '__le__', '__len__', '__lt__', '__ne__', '__new__', '__or__', '__rand__', '__reduce__', '__reduce_ex__', '__repr__', '__ror__', '__rsub__', '__rxor__', '__setattr__', '__sizeof__', '__str__', '__sub__', '__subclasshook__', '__xor__', 'add', 'clear', 'copy', 'difference', 'difference_update', 'discard', 'intersection', 'intersection_update', 'isdisjoint', 'issubset', 'issuperset', 'pop', 'remove', 'symmetric_difference', 'symmetric_difference_update', 'union', 'update']
  
  add-添加不可变元素
  集合中添加元素
  
  s3 # 原集合
  {6, 7, 8, 9}
  
  s3.add(1) # 添加1
  s3
  {1, 6, 7, 8, 9}
  
  s3.add(2) # 添加2
  s3
  {1, 2, 6, 7, 8, 9}
  
  s3.add([1,3,5])
  ---------------------------------------------------------------------------
  
  TypeError Traceback (most recent call last)
  
  in
  s3.add(tuple1) # 添加元组
  
  
  
  ----> 1 s3.add([1,3,5])
  
  
  
  TypeError: unhashable type: 'list'
  
  
  报错提示:列表是不可哈希,也就是可变类型的。之前我们说过:集合中的元素都是可哈希(不可变类型),所以不能直接添加
  
  list1 = [1,3,5]
  
  tuple1 = tuple(list1) # 列表转成元组,元组是不可变的
  
  tuple1
  (1, 3, 5)
  
  s3.add(tuple1)  # 添加元组
  s3
  {(1, 3, 5), 1, 2, 6, 7, 8, 9}
  
  update-更新集合
  
  更新集合中的元素,将两个集合中的元素组合在一起
  
  # 创建两个集合,有相同的元素“python”
  
  s8 = set(["python","java","c"])
  s9 = set(["python","go","javascript","html"])
  s8.update(s9)
  s8
  {'c', 'go', 'html', 'java', 'javascript', 'python'}
  
  生成的数据中自动将python去重了
  
  s9 # s9还是没有变化的
  {'go', 'html', 'javascript', 'python'}
  
  update的参数不仅仅是集合,它的参数是不可变数据类型:
  
  help(set.update) # 查看方法的文档信息
  Help on method_descriptor:
  
  update(...)
  
  Update a set with the union of itself and others.
  
  s9.update("hello")
  s9
  {'e', 'go', 'h', 'html', 'javascript', 'l', 'o', 'python'}
  
  s9.update((7,8,9))
  s9
  {7, 8, 9, 'e', 'go', 'h', 'html', 'javascript', 'l', 'o', 'python'}
  
  pop-随机删除
  
  随机删除一个元素,并且返回删除的结果。pop不能指定参数,也就是不能指定想要删除的元素
  
  s9.pop()
  'python'
  
  s9.pop()
  'html'
  
  s9.pop("python") # 不能带参数
  ---------------------------------------------------------------------------
  
  TypeError Traceback (most recent call last)
  
  in
  
  ----> 1 s9.pop("python") # 不能带参数
  
  TypeError: pop() takes no arguments (1 given)
  
  remove-指定删除
  删除的元素必须在集合中。如果不存在,则会报错
  
  s8
  {'c', 'go', 'html', 'java', 'javascript', 'python'}
  
  s8.remove("go")
  s8 # 结果显示go被删除了
  {'c', 'html', 'java', 'javascript', 'python'}
  
  s8.remove("go") # 再次删除go就会报错,因为go已经不存在了
  ---------------------------------------------------------------------------
  
  KeyError Traceback (most recent call last)
  
  in
  
  ----> 1 s8.remove("go") # 再次删除go就会报错,因为go已经不存在了
  
  KeyError: 'go'
  
  discard-指定删除
  指定删除某个元素,如果元素不存在,也不会报错。
  
  s8 # 原数据
  {'c', 'html', 'java', 'javascript', 'python'}
  
  s8.discard("html")
  s8 # 删除后的数据
  {'c', 'java', 'javascript', 'python'}
  
  s8
  {'c', 'java', 'javascript', 'python'}
  
  s8.discard("go")
  上面的结果表明:如果删除的元素不存在,也不会报错。这个是和remove不一样的地方
  
  clear-清空集合
  删除集合中的全部元素
  
  s8
  {'c', 'java', 'javascript', 'python'}
  
  s8.clear() # 清空了集合
  s8
  set()
  
  bool(s8) # bool值为False
  False
  
  不变的集合-frozenset()
  上面通过set方法创建的集合,我们了解到:集合是可变的,也就是可修改的,或者说不可哈希的。
  
  实际上还有一种方式创建的集合是不可变的:frozenset(),可以理解成冻集合,所以就不能进行修改等操作啦。
  
  f_set = frozenset("python")
  
  f_set
  frozenset({'h', 'n', 'o', 'p', 't', 'y'})
  
  我们查看下这个冻集合的操作方法
  
  print(dir(f_set)) # 冻集合
  ['__and__', '__class__', '__contains__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__ne__', '__new__', '__or__', '__rand__', '__reduce__', '__reduce_ex__', '__repr__', '__ror__', '__rsub__', '__rxor__', '__setattr__', '__sizeof__', '__str__', '__sub__', '__subclasshook__', '__xor__', 'copy', 'difference', 'intersection', 'isdisjoint', 'issubset', 'issuperset', 'symmetric_difference', 'union']
  
  print(dir(s9)) # set集合,非冻集合
  ['__and__', '__class__', '__contains__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__iand__', '__init__', '__init_subclass__', '__ior__', '__isub__', '__iter__', '__ixor__', '__le__', '__len__', '__lt__', '__ne__', '__new__', '__or__', '__rand__', '__reduce__', '__reduce_ex__', '__repr__', '__ror__', '__rsub__', '__rxor__', '__setattr__', '__sizeof__', '__str__', '__sub__', '__subclasshook__', '__xor__', 'add', 'clear', 'copy', 'difference', 'difference_update', 'discard', 'intersection', 'intersection_update', 'isdisjoint', 'issubset', 'issuperset', 'pop', 'remove', 'symmetric_difference', 'symmetric_difference_update', 'union', 'update']
  
  通过对比两种集合的操作方法,我们发现:冻集合中明显是少了很多增加、删除等方法,所以冻集合是不可变的
  
  集合运算
  在这个小节中介绍的是集合中的各种运算,比如:交集、并集、补集等
  
  in-元素判断
  
  s5
  {1, 2, 3, 4}
  
  1 in s5
  True
  
  6 in s5
  False
  
  issubset-子集与issuperset-超集
  
  A如果是B的子集,那么B就是A的超集;也就说A的元素全部在B中
  
  s10 = {1,2}  # 创建一个新的集合
  s10
  {1, 2}
  
  s10.issubset(s5) # s10是s5的子集
  True
  
  s5.issuperset(s10) # s5是s10的超集
  True
  
  s9
  {7, 8, 9, 'e', 'go', 'h', 'javascript', 'l', 'o'}
  
  s9.issubset(s5) # 很显然s9不是s5的子集
  False
  
  intersection-交集
  求两个集合的交集,使用intersection函数或者&
  
  print(s5)
  
  print(s10)
  {1, 2, 3, 4}
  
  {1, 2}
  
  s5.intersection(s10)
  {1, 2}
  
  s5 & s10
  {1, 2}
  
  union-并集
  使用函数union或者|来表示两个集合的并集,会生成一个新的对象
  
  print(s5)
  
  print(s9)
  {1, 2, 3, 4}
  
  {'javascript', 'o', 7, 'l', 'go', 'h', 8, 9, 'e'}
  
  s11 = s5|s9
  s11
  {1, 2, 3, 4, 7, 8, 9, 'e', 'go', 'h', 'javascript', 'l', 'o'}
  
  s5.union(s9)
  {1, 2, 3, 4, 7, 8, 9, 'e', 'go', 'h', 'javascript', 'l', 'o'}
  
  difference-差集、补集
  使用函数difference或者减号-
  
  print(s5)
  
  print(s10)
  {1, 2, 3, 4}
  
  {1, 2}
  
  s5 - s10
  {3, 4}
  
  s5.difference(s10)
  {3, 4}
  
  s10 - s5
  set()
  
  symmetric_difference-对称差集
  使用函数symmetric_difference或者symmetric_difference_update(原地更新数据)
  
  s12 = {1,3,4,5,7}
  
  s12
  {1, 3, 4, 5, 7}
  
  s5 # 原数据
  {1, 2, 3, 4}
  
  s5.symmetric_difference(s12)
  {2, 5, 7}
  
  s5 # 原数据没有改变
  {1, 2, 3, 4}
  
  s5.symmetric_difference_update(s12)
  s5 # 原数据为输出结果
  {2, 5, 7}
 

(编辑:我爱制作网_沈阳站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!