在上一篇《手把手陪您学Python》19——第一阶段小结中,我们对前一阶段学习的内容进行了一次总结,并通过编写一个较为复杂的程序进行了应用。同时,还给大家留了一个思考题,就是作为游戏的“设计者”,如何才能够一次猜对呢?
其实,只要让我们在程序运行的过程中,看到电脑产生的四位数字就可以。而方法呢,就是在电脑生成数字后,将这个数字“打印”出来就可以了。作为程序的设计者,是不是很有自豪感呢?所以我们可以想象,在一些大型游戏中,如果程序设计者,想给自己留个后门,增加战力甚至无敌,都不是一件困难的事了。
结束了第一阶段的学习,从今天开始,我们又要开启新的旅程了。在这一阶段中,我们将会学习到Python的多种数据类型,以及自定义函数的用法。在这一篇中,我们就对之前已经多次接触过的“列表”进行正式的介绍。
1、列表的定义
列表是Python中最常用的数据结构,它是用一对中括号括起来的数据序列。正如我们之前接触的那样,序列中的元素可以是数字、布尔值、字符串、列表、变量等数据类型,也可以是包括上述元素的列表,形成多层的嵌套。同时,列表的打印结果也是用中括号括起来的列表。
In [1]: list1 = [1, 'a'] # 列表元素是数字和字符串
list
Out[1]: [1, 'a']
In [2]: list2 = [1, 'a', list1] # 列表元素是数字、字符串和变量,同时变量又是一个列表,形成嵌套
list2
Out[2]: [1, 'a', [1, 'a']]
这里需要说明一点,可以作为列表元素的数据类型不止数字、布尔值、字符串、列表、变量这些,还有后面要学到的元组、字典、集合等数据类型,只不过因为还没有介绍到,所以在给列表进行定义和举例时,仅先以我们学过的内容为例(下同)。有兴趣的话,可以等我们学习到其它数据类型时,返回来测试一下这些数据类型是否可以作为列表的元素。
2、列表的索引和切片
列表的常见操作我们可以称之为“增删改查”,索引和切片就是其中的“查”,也是列表最重要的操作方法之一。列表索引和切片的方法与字符串完全相同,只不过字符串是以每一个字符作为操作对象,而列表是以每一个数据元素作为操作对象。
In [3]: string = 'Python'
list = ['P', 'y', 't', 'h', 'o', 'n']
In [4]: string[3]
Out[4]: 'h'
In [5]: list[3] # 索引的结果是对应的元素
Out[5]: 'h'
In [6]: string[2:5]
Out[6]: 'tho'
In [7]: list[2:5] # 切片的结果是对应元素组成的列表
Out[7]: ['t', 'h', 'o']
In [8]: list[3:4] # 切片的结果即使只有一个元素,结果也是列表
Out[8]: ['h']
In [9]: list[3:3] # 甚至切片的结果为空,结果也是一个空列表
Out[9]: []
因此,对于列表索引和切片的方法,就不再一一举例了,大家可以参考《手把手陪您学Python》7——字符串的索引、《手把手陪您学Python》8——字符串的切片两篇文章中的内容,对列表索引和切片的方法进行尝试。特别是对于切片参数比较复杂的情况,也希望大家逐一进行尝试,确保能够完全掌握,为后面灵活运用列表这一重要的数据结构奠定基础。
3、列表的修改
列表的“增删改”可以统称为列表的更新,这也是列表独有的特性。比如,我们下一篇文章中将要介绍的“元组”,就是不可以进行更新的。
列表的修改有两种情况。
一是对列表索引后的“元素”进行修改。就是直接将这个元素替换为修改后的元素,这个元素可以是数字、布尔值、字符串、列表等各种数据类型或者是值为这些数据类型的变量。
In [10]: list3 = [0, 1, 2, 3, 4, 5]
list3[0] = 'Python' # 索引后的元素替换成字符串
list3[1] = 10 # 索引后的元素替换成数字
list3[2] = ['a', 'b'] # 索引后的元素替换成列表,形成嵌套
list3[3] = list # 索引后的元素替换成变量
list3
Out[10]: ['Python', 10, ['a', 'b'], ['P', 'y', 't', 'h', 'o', 'n'], 4, 5]
二是对列表切片后的“列表”进行修改。此时,修改后的对象需要是一个可“遍历”的数据类型,比如字符串、列表或者是值为这些数据类型的变量。替换的过程,相当于把切片部分的列表元素抠下来,同时将修改后的对象拆分到最小的单元(字符串的每一个字符、列表的每一个元素)作为列表的元素,替换到被抠下来的元素的位置上。此种情况下的修改,不要求修改前后的元素个数相同。但因为数字或者布尔值无法被“遍历”,所以不能作为这种情况下的替换值。
In [11]: list4 = [0, 1, 2, 3, 4, 5]
list4[2:3] = ['a', 'b'] # 对比上例中对于第三个元素的修改,此时不是将切片后的元素替换成列表,而是将切片后的元素替换成新的列表中的元素
list4
Out[11]: [0, 1, 'a', 'b', 3, 4, 5]
In [12]: list5 = [0, 1, 2, 3, 4, 5]
list5[:-1] = ['a', 'b'] # 替换前后的元素个数可以不同
list5
Out[12]: ['a', 'b', 5]
In [13]: list6 = [0, 1, 2, 3, 4, 5]
list6[2:4] = [] # 替换为空列表,相当于删除列表中指定位置的元素
list6
Out[13]: [0, 1, 4, 5]
In [14]: list7 = [0, 1, 2, 3, 4, 5]
list7[-1:] = 1 # 因为数据不能够被“遍历”,替换为数字时报错
list7
Out[14]: ---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-53-3b2d30b5da1c> in <module>
1 list7 = [0, 1, 2, 3, 4, 5]
----> 2 list7[-1:] = 1 # 替换为非列表的数据元素报错
3 list7
TypeError: can only assign an iterable
In [15]: list8 = [0, 1, 2, 3, 4, 5]
list8[-3:] = 'Python' # 可以替换为字符串,但会先将字符串'Python'拆分到最小单元,再进行替换
list8
Out[15]: [0, 1, 2, 'P', 'y', 't', 'h', 'o', 'n']
In [16]: list9 = [0, 1, 2, 3, 4, 5]
list9[3:5] = ['P', 'y', 't', 'h', 'o', 'n'] # 可以替换为列表,也是将列表拆分成多个元素,再进行替换
list9
Out[16]: [0, 1, 2, 'P', 'y', 't', 'h', 'o', 'n', 5]
因为切片后要修改的数据类型要求可以被“遍历”,所以我们很快就能想到for循环语句了。也就是在切片后要替换的数据类型,与可以被for循环遍历的数据类型是一致的。虽然看上去完全不沾边的两个知识点,却因为相同的“遍历”要求而联系在了一起。
所以在这里多说几句。一个伟大的程序语言,绝不仅仅是一个个知识点或者语法规则的拼凑,其内在或者更高的层次上,一定会有更加普适性的规则以及逻辑。
不仅仅是刚刚讲到的这一点,包括我们之前学习的列表和字符串的索引和切片,使用的也是同样的规则与参数体系,后面要学习的很多数据类型甚至在数据分析中用到的更加复杂的多维数据结构,也遵循着同样的索引和切片原则。
这就要求我们在学习Python的时候,一是要把基本概念彻底了解清楚、吃透,二是要把不同知识点之间的内在联系和相同的规则体系联系起来,帮助我们加深了解、提高学习效率。这也是在《手把手陪您学Python》系列文章中,经常针对一个小小的知识点就把各种不同情况都罗列出来,让大家彻底搞清楚的原因。虽然看上去浪费了一些时间,学习起来也比较枯燥,但是当我们把几个知识点联系起来之后,就会发现这种方法才是更高效、更有价值的。
4、列表元素的增加
在上面列表的修改的介绍中,其实已经包括了一种增加列表元素的方法。也就是通过切片后进行修改的方式,间接实现在列表“任意”位置增加元素。但最常用的增加列表元素的方法是append()方法,其作用是在列表“末尾”添加新的元素或者对象。
在《手把手陪您学Python》10——字符串的函数中,我们讲过“函数”和“方法”的区别,简要来说就是函数的对象是写在括号里面的,而方法的对象是写在名称前面的。因为append()是一个方法,所以其操作的列表对象名称list要写在append的前面,而括号里写的是要在列表末尾增加的元素或者对象object。
list.append(object)
append()方法中的object参数可以是数字、布尔值、字符串、列表或者变量等,但只能有一个参数,也就是一次操作只能在列表后面增加一个元素。
In [17]: list10 = [0, 1, 2, 3, 4, 5]
list10.append(6) # 先在列表末尾增加数字6
list10.append('78') # 之后在更新后的列表后面增加字符串'7'
list10.append([9, 10]) # 最后再在更新后的列表增加列表[8, 9],此时的参数也只有一个
list10
Out[17]: [0, 1, 2, 3, 4, 5, 6, '78', [9, 10]]
In [18]: list11 = [0, 1, 2, 3, 4, 5]
list11.extend(1, 3) # 当参数超过一个时报错
list11
Out[18]: ---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-14-8845285907af> in <module>
1 list11 = [0, 1, 2, 3, 4, 5]
----> 2 list11.extend(1, 3)
3 list11
TypeError: extend() takes exactly one argument (2 given)
除append()方法外,在列表末尾增加元素的方法还有extend()。extend()方法在括号中的参数也只能有一个,与append()不同的是,extend()的参数是要求能够被“遍历”的(类似列表切片后的修改),之后会先把参数中的数据拆分成最小的单元,一次性在列表末尾添加多个元素。数字、布尔值等数据类型因为不可被“遍历”,所以不能做为extend()的参数。
list.extend(object)
In [19]: list12 = [0, 1, 2, 3, 4, 5]
list12.extend('78') # 先将字符串'78'拆分成'7'和'8',再添加到列表末尾
list12.extend([9, 10]) # 之后将列表拆分成多个元素,在刚才更新后的列表后进行添加
list12
Out[19]: [0, 1, 2, 3, 4, 5, '7', '8', 9, 10]
In [20]: list13 = [0, 1, 2, 3, 4, 5]
list13.extend([6, 7], '8') # 当参数超过一个时报错
list13
Out[20]: ---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-20-13fee015b48c> in <module>
1 list13 = [0, 1, 2, 3, 4, 5]
----> 2 list13.extend([6, 7], '8') # 当参数超过一个时报错
3 list13
TypeError: extend() takes exactly one argument (2 given)
In [21]: list14 = [0, 1, 2, 3, 4, 5]
list14.extend(6) # 当参数为一个不可被“遍历”的数据类型时报错
list14
Out[21]: ---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-23-f49cfc1155db> in <module>
1 list14 = [0, 1, 2, 3, 4, 5]
----> 2 list14.extend(6) # 当参数为一个不可被“遍历”的数据类型时报错
3 list14
TypeError: 'int' object is not iterable
5、列表元素的删除
在上面列表的修改的介绍中,也已经包括了一种删除列表元素的方法。就是通过切片后修改成“空列表”的方式,间接实现删除列表“任意”位置元素的目的。但最常用的删除列表元素的方法是del语句,其作用是将列表索引或切片的部分直接删除。
del list[a:b]
In [22]: list15 = [0, 1, 2, 3, 4, 5]
del list15[2] # 索引后删除一个元素
list15
Out[22]: [0, 1, 3, 4, 5]
In [23]: list16 = [0, 1, 2, 3, 4, 5]
del list16[2:4] # 切片后删除多个元素
list16
Out[23]: [0, 1, 4, 5]
除了del语句,还有一种删除列表元素的方法remove()方法。它是将列表中符合某个值的第一匹配项进行删除的方法。也就是说,del是按照元素在列表中的位置进行删除,而remove()是按照元素值进行删除。同样,remove()的参数也只能有一个。
list.remove(object)
In [24]: list17 = [0, 1, 2, 3, 4, 5, 4, 3, 2, 1]
list17.remove(3) # 只删除与参数值相同的第一个匹配项
list17
Out[24]: [0, 1, 2, 4, 5, 4, 3, 2, 1]
In [25]: list18 = [0, [1, 2], 3, 4, 5, 4, 3, [1, 2]]
list18.remove([1, 2]) # 只删除与参数值相同的第一个匹配项
list18
Out[25]: [0, 3, 4, 5, 4, 3, [1, 2]]
6、列表的运算
列表的运算其实就是刚才说的,遵循着Python更高阶的统一规则,与字符串的运算保持一致,而不是列表的特定语法要求。
In [26]: [1, 2, 3] + [4, 5, 6] # 与字符串一样,+也是拼接运算
Out[26]: [1, 2, 3, 4, 5, 6]
In [27]: [1, 2, 3] * 3 # *也是重复输出
Out[27]: [1, 2, 3, 1, 2, 3, 1, 2, 3]
In [28]: [1, 2, 3] == [1, 2, 3] # 比较运算,要完全相同
Out[28]: True
In [29]: [1, 2, 3] != [1, 2, 3] # 比较运算
Out[29]: False
In [30]: [2, 2, 3] > [1, 2, 2, 4] # 比较运算,只比较第一个元素
Out[30]: True
In [31]: 1 in [1, 2, 3] # 成员运算
Out[31]: True
In [32]: 1 not in [1, 2, 3] # 成员运算
Out[32]: False
In [33]: [1, 2, 3] is [1, 2, 3] # 身份运算,值相同,但内存地址不同,具体请参见《手把手陪您学Python》13——运算
Out[33]: False
7、列表的函数
下表中列举出了四种常用的列表函数,除第四个我们暂时还用不上,其它的函数都可以应用在我们的程序上了。特别是计算列表元素个数的函数len(),是我们日后经常会使用到的,也常会与for循环配合使用。
序号 | 函数 | 作用 |
1 | len(list) | 返回列表元素个数 |
2 | max(list) | 返回列表元素最大值 |
3 | min(list) | 返回列表元素最小值 |
4 | list(seq) | 将元组转换为列表 |
In [34]: day_lst = ['星期日', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六']
for i in range(len(day_lst)):
print("每周的第{}天是{}。".format(i+1,day_lst[i]))
Out[34]: 每周的第1天是星期日。
每周的第2天是星期一。
每周的第3天是星期二。
每周的第4天是星期三。
每周的第5天是星期四。
每周的第6天是星期五。
每周的第7天是星期六。
In [35]: list19 = [1, 2, 3]
print("由数字组成的列表,最大值和最小值是按照ASCII码从小到大排序的,因此list19的最大值是{},最小值是{}。".format(max(list19), min(list19)))
Out[35]: 由数字组成的列表,最大值和最小值是按照ASCII码排序的,因此list19的最大值是3,最小值是1。
In [36]: list20 = ['a', 'b', 'c']
print("由字符串组成的列表,最大值和最小值也是按照ASCII码从小到大排序的,因此list20的最大值是{},最小值是{}。".format(max(list20), min(list20)))
Out[36]: 由字符串组成的列表,最大值和最小值也是按照ASCII码从小到大排序的,因此list20的最大值是c,最小值是a。
In [37]: list21 = ['手', '把', '手', '陪', '您', '学']
print("由中文组成的列表,最大值和最小值是按照unicode从小到大排序的,因此list21的最大值是{},最小值是{}。".format(max(list21), min(list21)))
Out[37]: 由中文组成的列表,最大值和最小值是按照unicode从小到大排序的,因此list21的最大值是陪,最小值是a。
In [38]: list22 = ['手', '把', '手', '陪', '您', '学', 'a', 'b', 'c']
print("字符串只能和字符串比较,因此list22的最大值是{},最小值是{}。".format(max(list22), min(list22)))
Out[38]: 字符串只能和字符串比较,因此list22的最大值是陪,最小值是a。
In [39]: list23 = ['手', '把', '手', '陪', '您', '学', 1, 2, 3]
max(list23) # 字符串和数字不能混合比较
Out[39]: ---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-30-bd7a314f9f23> in <module>
1 list23 = ['手', '把', '手', '陪', '您', '学', 1, 2, 3]
----> 2 max(list23)
TypeError: '>' not supported between instances of 'int' and 'str'
In [40]: list24 = [[1, 2, 3], [2, 2, 1]]
print("列表间的比较也是根据列表中第一个字符的值进行比较,因此list24的最大值是{},最小值是{}。".format(max(list24), min(list24)))
Out[40]: 列表间的比较也是根据列表中第一个字符的值进行比较,因此list24的最大值是[2, 2, 1],最小值是[1, 2, 3]。
8、列表的方法
刚刚我们已经学习了append()和remove()两种列表的方法,分别是增加列表元素和删除列表元素。下表中还列举出了另外九种列表方法,后面会对其中比较常用的方法进行举例。其它未做示例的方法还请大家自行尝试,相信学习了这么长时间的Python,大家一定可以做到的。
序号 | 方法 | 方法 |
1 | list.append(obj) | 在列表末尾添加新的对象 |
2 | list.count(obj) | 统计某个元素在列表中出现的次数 |
3 | list.extend(seq) | 在列表末尾一次性追加另一个序列中的多个值(用新列表扩展原来的列表) |
4 | list.index(obj) | 从列表中找出某个值第一个匹配项的索引位置 |
5 | list.insert(index, obj) | 将对象插入列表 |
6 | list.pop([index=-1]) | 移除列表中的一个元素(默认最后一个元素),并且返回该元素的值 |
7 | list.remove(obj) | 移除列表中某个值的第一个匹配项 |
8 | list.reverse() | 反向列表中元素 |
9 | list.sort(cmp=None, key=None, reverse=False) | 对原列表进行排序 |
10 | list.clear() | 清空列表 |
11 | list.copy() | 复制列表 |
In [41]: list25 = ['《', '手', '把', '手', '陪', '您', '学', 'P', 'y', 't', 'h', 'o', 'n', '》']
list25.sort() # 与比较运算一样,同样类型的元素内部才能够排序
list25
Out[41]: ['P', 'h', 'n', 'o', 't', 'y', '《', '》', '学', '您', '手', '手', '把', '陪']
In [42]: list26 = ['《', '手', '把', '手', '陪', '您', '学', 'P', 'y', 't', 'h', 'o', 'n', '》']
list26.index('P')
Out[42]: 7
In [43]: list27 = [1, 2, 3, 4, 5, 2, 3, 4, 5, 2, 3]
list27.count(3)
Out[43]: 3
In [44]: list28 = [0, 1, 2, 3, 4, 5]
list28.insert(3, 'Python')
list28
Out[44]: [0, 1, 2, 'Python', 3, 4, 5]
In [45]: list29 = [0, 1, 2, 3, 4, 5]
list29.pop(3)
list29
Out[45]: [0, 1, 2, 4, 5]
以上就是Python列表相关内容的介绍了,虽然看上去内容比较多,但我们用一篇文章的内容就全部介绍完了。这是因为之前介绍字符串、运算等的内容,对列表来说很多都是适用的,给我们学习列表省了很大力气,不用再从基础的概念学起,通过几个实例就能了解的非常清楚了。
可以说,这就是我们学习的成果了!而且越学到后面,大家的这种体会就会越来越强烈,所以大家一定要把第一阶段的内容全部吃透,便于我们后面更好的学习和应用。
下一篇将要给大家介绍的是元组,因为元组可以看做是不允许修改的列表,所以很多属性、方法都与列表完全相同,所以学习起来会非常轻松,敬请关注。
感谢阅读本文!如有任何问题,欢迎留言,一起交流讨论^_^
欢迎扫描下方二维码,关注“亦说Python”公众号,阅读《手把手陪您学Python》系列文章的其他篇目,或点击下方链接直达。
《手把手陪您学Python》3——PyCharm的安装和配置
《手把手陪您学Python》5——Jupyter Notebook
For Fans:关注“亦说Python”公众号,回复“手20”,即可免费下载本篇文章所用示例语句。
