《手把手陪您学Python》24——集合

在上一篇《手把手陪您学Python》23——内置序列函数中,我们学习了4种Python中内置的序列函数,同时学习了利用序列函数构建字典的方法。

在这一篇中,我们将学习这一阶段中最后一种数据结构——集合。集合的概念我们并不陌生,在大学数学以及高中,都涉及到了一点集合的知识,像我们知道的交集、并集等,都是针对集合进行的操作。

今天,我们会对Python中集合的概念以及相关的操作方法给大家进行系统地讲解,同时还会将之前学习过的数据结构(列表、元组、字典)和标量(字符串、数字、布尔值)等加入到今天的示例中,以便大家能够对之前学过的内容有一个整体的认知和复习。

1、集合的定义

集合是一个无序的不重复元素序列,可以使用大括号{}或者set()函数创建集合。集合的元素可以是数字、布尔值、字符串、元组等不可变的类型,但不可以是列表、字典等可变的类型,也就是说集合的元素必须能够“哈希化”(可参见《手把手陪您学Python》22——字典中的扩展内容)。

同时,集合最重要的特性是“无序”和“不重复”,因此,集合无法被索引,重复的元素放入集合中会被“去重”。

In [1]: {1, 'a', True, (3, 2), 1}   # 使用{}是最容易的定义集合方法,重复的元素会被去掉(True也是1,因此也会被去重),因为无序,顺序也可能会调整
Out[1]: {(3, 2), 1, 'a'}

In [2]: {[1, 2], 1}   # 列表不能作为集合的元素
Out[2]: ---------------------------------------------------------------------------
        TypeError                                 Traceback (most recent call last)
        <ipython-input-14-cb9a458f6989> in <module>
        ----> 1 {[1, 2], 1}   # 列表不能作为集合的元素
        
        TypeError: unhashable type: 'list'

In [3]: {
   
   {1:1}, 1}   # 字典也不能作为集合的元素
Out[3]: ---------------------------------------------------------------------------
        TypeError                                 Traceback (most recent call last)
        <ipython-input-15-97fed40bc698> in <module>
        ----> 1 {
   
   {1:1}, 1}   # 字典也不能作为集合的元素
        
        TypeError: unhashable type: 'dict'

使用set()函数定义集合时,set()会采用遍历的方式,对参数拆分后形成集合。对于不能被遍历的数据类型,不能够直接作为set()的参数,而需要将其作为元组的元素,元组作为set()的参数。

In [4]: set("Good")   # 字符串被拆分为字母,同时去重
Out[4]: {'G', 'd', 'o'}

In [5]: set(123)   # 数字因为不能被遍历,所以不能够使用set()生成集合
Out[5]: ---------------------------------------------------------------------------
        TypeError                                 Traceback (most recent call last)
        <ipython-input-30-9becc342fd9e> in <module>
        ----> 1 set(123)
        
        TypeError: 'int' object is not iterable

In [6]: set((123,))   # 注意定义只包含一个元素的元组的方法
Out[6]: {123}

因为set()的参数只能有一个,所以当定义包括多个元素的集合时,都要放入元组内。列表、字典因为能够被遍历,所以也能够作为set()的参数,并将其元素添加到集合中。

In [7]: set(("Good", 123, 123))
Out[7]: {123, 'Good'}

In [8]: set(["Good", 123, 123])
Out[8]: {123, 'Good'}

In [9]: set({1:2,'3':'4'})   # 需要注意的是,当字典作为元素时,只有键会被遍历并添加到集合中
Out[9]: {1, '3'}

在定义空集合时,只能使用set()函数,因为{}是定义空字典的方法。

In [10]: print("set()的类型是{},{
   
   {}}的类型是{}".format(type(set()), type({})))   # 注意字符串的格式化输出方法中,输出{}的方法
Out[10]: set()的类型是<class 'set'>,{}的类型是<class 'dict'>

2、集合元素的增加

在集合中增加元素的方法有两种,一种是.add()方法,一种是.update()方法。

.add()方法只能有一个参数,且参数必须是不可变的(即可以哈希化)。

In [11]: set1 = set((1, 2, 3))
         set1.add(4)
         set1
Out[11]: {1, 2, 3, 4}

In [12]: set1.add(4, 5, 6)   # 只能有一个参数
         set1
Out[12]: ---------------------------------------------------------------------------
         TypeError                                 Traceback (most recent call last)
         <ipython-input-6-fc53492f5320> in <module>
         ----> 1 set1.add(4, 5, 6)
               2 set1
        
         TypeError: add() takes exactly one argument (3 given)


In [13]: set1.add((4, 5, 6))   # 元组中包含的多个元素,只作为一个元素(元组)添加到集合中,这是与set()函数的区别
         set1
Out[13]: {(4, 5, 6), 1, 2, 3, 4}

In [14]: set1.add([4, 5, 6])   # 列表、字典因为都是可变的,不能作为.add()的参数
         set1
Out[14]: ---------------------------------------------------------------------------
         TypeError                                 Traceback (most recent call last)
         <ipython-input-9-ed1640e4e4fc> in <module>
         ----> 1 set1.add([4, 5, 6])   # 列表、字典因为都是可变的,不能作为.add()的参数
               2 set1    
        
         TypeError: unhashable type: 'list'

.update()方法添加元素的方式与.add()完全不同,后者是参数是什么元素,就在集合中添加什么元素,而前者是通过遍历的方式,将参数中的所有元素进行遍历,一一添加到集合中。

因此,像数字、布尔值这种不能被遍历的数据类型,是不能作为.update()方法的参数的。而列表、字典等可变的元素,虽然不能作为集合的元素,但是可以通过.update()方法进行遍历,而将其元素添加到集合中,而且.update()方法也不限制元素的个数。

In [15]: set2 = set((1, 2, 3))

In [16]: set2.update(4)   # 数字不能遍历,所以报错
         set2
Out[16]: ---------------------------------------------------------------------------
         TypeError                                 Traceback (most recent call last)
         <ipython-input-16-5573d88f6ffa> in <module>
         ----> 1 set2.update(4)   # 数字不能遍历,所以报错
               2 set2
          
         TypeError: 'int' object is not iterable

In [17]: set2.update((4))   # (4)代表4加上小括号的数学运算,所以还是4,报错
         set2
Out[17]: ---------------------------------------------------------------------------
         TypeError                                 Traceback (most recent call last)
         <ipython-input-17-1e5a31168b76> in <module>
         ----> 1 set2.update((4))   # (4)代表4加上小括号的数学运算,所以还是4,报错
               2 set2
        
         TypeError: 'int' object is not iterable

In [18]: set2.update((4,))   # 注意只有一个元素的元组的定义方法
         set2
Out[18]: {1, 2, 3, 4}

In [19]: set2.update((4, 5), "Good", ['a', 'd', True, False], {6:7, '8':'9', 'X':'Y'})   # 请大家试试看能否得到与输出结果一致的答案,注意字典的遍历结果是什么
         set2
Out[19]: {1, 2, 3, 4, 5, 6, '8', False, 'G', 'X', 'a', 'd', 'o'}

3、集合元素的删除

集合元素的删除方法一共有三种,分别是.remove()方法、.discard()方法和.pop()方法,此外还有一个清空集合的方法.clear()。

.remove()方法可以直接从集合中删除特定元素,如果该元素不存在,则报错。

In [20]: set3 = {1, 2, 3, 'a', 'b', 'c'}

In [21]: set3.remove(3)
         set3
Out[21]: {1, 2, 'a', 'b', 'c'}

In [22]: set3.remove(3)   # 3已经在上一步中被删除了,因此报错
         set3
Out[22]: ---------------------------------------------------------------------------
         KeyError                                  Traceback (most recent call last)
         <ipython-input-27-6cccfd8ba26e> in <module>
         ----> 1 set3.remove(3)   # 3已经在上一步中被删除了,因此报错
               2 set3
          
          
         KeyError: 3

.discard()方法也可以直接从集合中删除特定元素,但该元素不存在时,不会报错。

In [23]: set3.remove('b')
         set3
Out[23]: {1, 2, 'a', 'c'}

In [24]: set3.discard('b')   # 虽然'b'已经在上一步中被删除的,也不会报错
         set3
Out[24]: {1, 2, 'a', 'c'}

.pop()方法则是随机从集合中删除某元素,并且返回被删除元素的元素值。虽然说是随机删除,但是在交互模式中,.pop()方法会删除集合排序后左侧的第一个元素(虽然无序,但是集合一般会按ASCII的顺序进行排序,从前面的实例中也可以看到)。

In [25]: set3.pop()   # 排序后左侧第一个元素是1
Out[25]: 1

In [26]: set3
Out[26]: {2, 'a', 'c'}

.clear()方法就是将集合中的元素全部删除,形成一个空集合。

In [27]: set3.clear()
         set3
Out[27]: set()

4、集合的运算

集合的运算就是指我们比较熟悉的交集、并集等,此外,还有我们不太熟悉的差集和对称差集。

In [28]: set4 = {1, 2, 3, 4, 5}
         set5 = {4, 5, 6, 7, 8, 9}

In [29]: set4.union(set5)   # 并集,或者使用二元操作符(set4 | set5)
Out[29]: {1, 2, 3, 4, 5, 6, 7, 8, 9}

In [30]: set4 | set5   # 其它运算不再列举二元操作符的实例
Out[30]: {1, 2, 3, 4, 5, 6, 7, 8, 9}

In [31]: set4.intersection(set5)   # 交集,或者使用二元操作符(set4 & set5)
Out[31]: {4, 5}

In [32]: set4.difference(set5)   # 差集,即在set4但不在set5的元素,或者使用二元操作符(set4 - set5)
Out[32]: {1, 2, 3}

In [33]: set4.symmetric_difference(set5)   # 对称差集,即在set4和set5但不同时在set4和set5的元素,或者使用二元操作符(set4 ^ set5)
Out[33]: {1, 2, 3, 6, 7, 8, 9}

在应用上述方法进行运算时,并不会改变set4和set5的值。如果想在运算的同时,改变se4的值,就需要用到.update()方法,或者在上述方法的基础上增加update字样。同时二元操作符也有相应的改变,就像我们之前介绍的a=a+1与a+=1等效一样。

In [34]: set4.update(set5)   # 并集并赋值给set4,或者使用二元操作符(set4 |= set5)
         set4
Out[34]: {1, 2, 3, 4, 5, 6, 7, 8, 9}

In [35]: set4 = {1, 2, 3, 4, 5}
         set5 = {4, 5, 6, 7, 8, 9}
         set4.intersection_update(set5)
         set4   # 交集并赋值给set4,或者使用二元操作符(set4 &= set5)
Out[35]: {4, 5}

其它类似的方法还有a.difference_update(b)(二元操作符:a -= b),a. symmetric_difference_update(b)(二元操作符:a ^= b),这里就不一一举例了。

5、集合的判断

集合的判断主要是判断一个集合是否包含与另一集合中的相关运算。

In [36]: set6 = {1, 2, 3, 4, 5}
         set7 = {1, 2, 3}

In [37]: set7.issubset(set6)   # set7是不是set6的子集
Out[37]: True

In [38]: set6.issuperset(set7)   # set6是不是set7的父集
Out[38]: True

In [39]: set8 = {6, 7}
         set6.isdisjoint(set8)   # 如果set6和set8没有交集,返回True
Out[39]: True

In [40]: set9 = {1, 2, 3}
         1 in set9   # 可以使用我们之前学过的in,来判断一个元素是否包含在集合中
Out[40]: True

In [41]: set10 = {1, 2, 3}
         set9 == set10   # 判断两个集合是否相同,这里不能用is,因为内存地址不同
Out[41]: True

6、集合的函数

上面我们介绍的都是集合的方法,下面我们介绍一个集合的函数len(),也就是计算集合的元素个数的函数。

In [42]: len({1, 'a', True, (3, 2), 1})
Out[42]: 3

以上就是我们对于Python集合的介绍了,至此我们已经将Python中最基础的几个数据结构都介绍完了。下一篇,我们将介绍列表、集合和字典的推导式,这也是Python最受欢迎的语言特性之一,敬请关注。


感谢阅读本文!如有任何问题,欢迎留言,一起交流讨论^_^

要阅读《手把手陪您学Python》系列文章的其他篇目,请关注公众号点击菜单选择,或点击下方链接直达。

《手把手陪您学Python》1——为什么要学Python?

《手把手陪您学Python》2——Python的安装

《手把手陪您学Python》3——PyCharm的安装和配置

《手把手陪您学Python》4——Hello World!

《手把手陪您学Python》5——Jupyter Notebook

《手把手陪您学Python》6——字符串的标识

《手把手陪您学Python》7——字符串的索引

《手把手陪您学Python》8——字符串的切片

《手把手陪您学Python》9——字符串的运算

《手把手陪您学Python》10——字符串的函数

《手把手陪您学Python》11——字符串的格式化输出

《手把手陪您学Python》12——数字

《手把手陪您学Python》13——运算

《手把手陪您学Python》14——交互式输入

《手把手陪您学Python》15——判断语句if

《手把手陪您学Python》16——循环语句while

《手把手陪您学Python》17——循环的终止

《手把手陪您学Python》18——循环语句for

《手把手陪您学Python》19——第一阶段小结

《手把手陪您学Python》20——列表

《手把手陪您学Python》21——元组

《手把手陪您学Python》22——字典

《手把手陪您学Python》23——内置序列函数

For Fans:关注“亦说Python”公众号,回复“手24”,即可免费下载本篇文章所用示例语句。

亦说Python——Python爱好者的学习分享园地

猜你喜欢

转载自blog.csdn.net/mnpy2019/article/details/102782511