5 列表、元组和字典 大千世界的逻辑很复杂,要想编写出具有强大功能的程序,还 需进一步学习如何表达更复杂的数据,进而构建具有更强大功能的 程序。Python提供了一种序列结构存储多项数据,这些数据在序列 中有序存储,我们可以通过数据在序列中的位置检索到它,还可以 对序列中的数据进行各种各样的操作。 Python中常见的序列有字符串、列表(list) 、元组和字典等。第4 章讲解的字符串就是一种常见的序列。本章主要介绍Python中的 列表、元组和字典。 第5 章 列表、元组和字典 5.1 管理水果列表 小明开了一个水果店,由于季节更换的原因,经常需要更新在售水果列表,增加新上市 的水果或者删除不再销售的水果,按要求更新水果列表。 该案例可创建列表保存在售水果清单,再根据需要对清单中的水果进行增加或删除。 下面将介绍创建列表及对列表进行增加元素和删除元素的操作,通过这些内容的学习,可解 决更新水果列表这一案例的编程。 5.1.1 创建列表 列表是Python中重要的数据类型之一,是一组任意对象的有序集合。创建列表的语法 很简单,使用中括号将用逗号分隔的不同的数据项标注起来即可,语法如下所示。 [ele1,ele2,ele3,…] 其中,ele1,ele2,ele3,…可以是任意类型的对象。看下面的示例。 【例5-1】 创建包含5个字符串元素的列表。 fruits = ['苹果', '草莓', '香蕉', '梨', '百香果'] print(fruits) 在Python中也可以创建不含元素的空列表,即列表长度为0的列表。 【例5-2】 创建空列表。 fruits1 = [] #空列表,即len(fruits1)为0 fruits2 = list() print(len(fruits1)) print(len(fruits2)) 列表中的元素可以是简单对象,也可以是列表、元组等集合对象。 【例5-3】 创建一个包含多个列表元素的列表。 79 #peoples 长度为6,包含6 个列表元素 peoples = [['张三', 1.84],['李四', 1.65],['王五', 1.90],['赵六', 1.88],['钱七', 1.92],['孙八', 1.77]] print(len(peoples)) 5.1.2 通过索引使用元素 列表中的各个元素都有各自的索引,可以通过索引使用列表中的元素。列表中的元素 从左到右的索引顺序是[0,n-1],从右到左的索引顺序是[-1,-n],其中n是列表的长度。 看下面的示例。 【例5-4】 创建长度为4的list1,包含2个数字元素、1个字符串元素、1个列表元素。 list1 = [2020, 10, '2020-1-1', ['hi', 1, 2]] len(list1) ==4 #通过索引使用元素 print(list1[0] ==list1[-4] ==2020) #输出True print(list1[2] ==list1[-2] =='2020-1-1') #输出True print(list1[3] ==list1[-1] ==['hi', 1, 2]) #输出True 列表中的元素是有序的。下面两个列表的比较说明了即使列表中包含的元素相同,但 元素排序不同也是不同的列表。 【例5-5】 两个列表的比较。 a=[1,2,3] b=[3,2,1] print(a==b) #输出False,==判断两个列表的值是否相等 print(a is b) #输出False,is 判断两个列表是否为同一个对象 5.1.3 列表切片 在Python中处理列表的部分元素,称为列表切片。切片是列表的常用操作,对于一个 列表,其切片操作的命令格式如下。 list_name[start:end:step] 其中,start、end是元素的索引,start是第一个截取的元素索引,end是第一个不截取的元素 索引,start:end表示返回从第一个数字索引到第二个数字索引(不包括第二个数字索引的 值)的一个新列表。step是截取的步长,可取正值或负值。step取正值时表示正向截取,正 向截取列表时,start的索引位置必须在end的索引位置的前面;step取负值时表示反向截取 列表,反向截取列表时,start的索引位置必须在end的索引位置的后面。step默认状态下取 1,表示正向逐个截取元素。 80 第5 章 列表、元组和字典 1.切片示例 【例5-6】 切片示例1。 list_a = [1, 2, 3, 4, 5, 6] print(list_a[0:3]) #输出[1, 2, 3] print(list_a[:3]) #start 默认时默认是0,输出[1, 2, 3] print(list_a[1:5]) #输出[2, 3, 4, 5] print(list_a[1:7]) #给end 赋一个比最后一个元素的索引更大的值表示取到最后 #一个元素,输出[2, 3, 4, 5, 6] print(list_a[1:]) #end 默认时默认取到最后一个元素,输出[2, 3, 4, 5, 6] print(list_a[:]) #start 和end 都默认时表示取整个列表,输出[1, 2, 3, 4, 5, 6] print(list_a[3:1]) #输出[],step 为正值时,正向切片列表,start 应该比end 大,否 #则返回空列表 print(list_a[::2]) #step 为2,输出[1, 3, 5] 上面的例子里,start、end和step都为正值,但这3个值也可以为负值。我们知道,列表 的索引也可以从右往左逆序编号为[-1,-n],因此,当start和end为负值时,表示是按列 表的反方向对列表元素进行索引,-1代表列表的倒数第一个元素,-2代表列表的倒数第 二个元素,以此类推。 【例5-7】 切片示例2。 本示例是start和end为负值,step为正值的情况(注意,step为正时,依然是正向截取 列表)。 list_b = [1, 2, 3, 4, 5, 6] list_b[-1] #输出6 list_b[-2:] #输出[5, 6] list_b[:-2] #输出[1, 2, 3, 4] list_b[-2:-4] #step 为正值,正向截取列表,输出空列表[] list_b[-4:-2] #输出[3, 4] list_b[-3:-1] #输出[4, 5] 【例5-8】 切片示例3。 本示例是step为负值(step为负值时,反向截取列表)的情况。 list_c = [1, 2, 3, 4, 5, 6] list_c[:-3:-1] #输出[6, 5] list_c[1::-1] #输出[2, 1] list_c[-2:-3:-1] #输出[5] list_c[-4:-3:-1] #输出[] list_c[1:4:-1] #输出[] list_c[1:-1:-1] #输出[] list_b[3:1:-1] #输出[4, 3] 81 可以看到,step为负值时,start的索引位置必须在end的索引位置的后面,否则只能得 到空列表,这正是因为step为负值时是反向截取列表的。反向截取列表时,start默认为 -1,也就是从列表倒数第一个元素开始截取,end默认截取到列表的第一个元素。 2.对水果列表进行切片 管理水果列表时,也需要用到列表的切片操作。下面通过指定要使用的第一个元素和 最后一个元素的索引对水果列表创建切片,代码如下所示。 【例5-9】 水果列表切片示例1。 fruits = ['苹果','草莓','香蕉','梨', '百香果'] print(fruits[0:3]) #输出索引0~2 的3 个列表元素,['苹果', '草莓', '香蕉'] print(fruits[1:4]) #输出索引1~3 的3 个列表元素,['草莓', '香蕉', '梨'] print(fruits[:2]) #没有指定索引时,即从索引0 开始,输出索引0 和1 的两个列 #表元素,相当于fruits[0:2],['苹果', '草莓'] print(fruits[2:]) #输出含索引2 及其后的所有元素,['香蕉', '梨', '百香果'] print(fruits[-2:]) #输出列表中的最后两个元素,['梨', '百香果'] 下面的示例使用for循环对列表遍历,实现遍历列表中的部分元素功能,示例代码如下。 【例5-10】 水果列表切片示例2。 fruits = ['苹果','草莓','香蕉','梨', '百香果'] for fruits in fruits[:4]: print("My favorite fruits is " + fruits); 图5-1 for循环遍历列表 此程序使用for循环fruits列表中从索引0开始的 4个元素,相当于遍历了fruits[0:4]这个切片,最后打 印出的即前面4 个列表元素的值。代码运行结果如 图5-1所示。 3.复制列表 要复制列表,可创建一个包含整个列表的切片,即 同时省略起始索引和终止索引对列表进行切片。这相 当于让Python创建一个开始于第一个元素,终止于最后一个元素的切片,即复制整个列表。 示例代码如下。 【例5-11】 复制列表示例1。 #列表复制示例代码 fruits = ['苹果','草莓','香蕉','梨', '百香果'] my_fruits = fruits [:] #省略起始索引和终止索引 print(fruits) print(my_fruits) fruits.append('猕猴桃') #往fruits 中追加元素 82 第5 章 列表、元组和字典 my_fruits.append('西瓜') #往my_ fruits 中追加元素 print(fruits) print(my_fruits) 代码运行结果如图5-2所示。 图5-2 复制列表 Python中的变量存储的是对列表对象的引用,而不是对象本身。看下面这段代码。 【例5-12】 列表变量示例。 fruits = ['苹果','草莓','香蕉','梨', '百香果'] my_fruits = fruits print(fruits) #['苹果', '草莓', '香蕉', '梨', '百香果'] print(my_fruits) #['苹果', '草莓', '香蕉', '梨', '百香果'] fruits.append('猕猴桃') my_fruits.append('西瓜') print(fruits) #['苹果', '草莓', '香蕉', '梨', '百香果', '猕猴桃', '西瓜'] print(my_fruits) #['苹果', '草莓', '香蕉', '梨', '百香果', '猕猴桃', '西瓜'] 代码fruits= ['苹果','草莓','香蕉','梨','百香果']执行时,Python先为列表对象['苹果', '草莓','香蕉','梨','百香果']分配内存空间,然后将变量fruits指向该列表对象。代码 my_fruits=fruits表示将fruits变量赋给my_ fruits变量,此时Python只是将新变量 my_fruits也指向fruits变量所指的列表对象['苹果','草莓','香蕉','梨','百香果'],即这两个 变量都指向同一个列表对象。可见,无论通过哪个变量为所指的列表对象添加元素,其实都 在给同一个列表对象添加元素。因此,最后两行代码的print输出结果相同。代码运行结果 如图5-3所示。 图5-3 变量指向列表对象示例 83 5.1.4 增加列表元素 小明的水果店里已经有一批水果,现在要增加一批水果。假如已有的水果列表为 fruits1,新增的水果列表为fruits2,下面使用列表的加法功能实现两个列表的元素汇集。 【例5-13】 列表的加法。 fruits1 = ['苹果','草莓','香蕉','梨', '百香果'] fruits2 = ['猕猴桃','西瓜','樱桃'] fruits = fruits1 + fruits2 print(fruits1) #['苹果', '草莓', '香蕉', '梨', '百香果'] print(fruits2) #['猕猴桃', '西瓜', '樱桃'] print(fruits) #['苹果', '草莓', '香蕉', '梨', '百香果', '猕猴桃', '西瓜', '樱桃'] 可以看出,列表的加法就是把两个列表所包含的元素合并在一起,形成一个汇总所有元 素后的列表。 给已有的列表中添加元素也可使用append()方法,该方法把传入的参数追加到原列表 的最后,示例代码如下。 【例5-14】 列表的append()方法。 fruits = ['苹果','草莓','香蕉','梨', '百香果'] fruits.append('猕猴桃') print(fruits) fruits.append(['西瓜','樱桃']) print(fruits) append()方法既可追加单个值,也可追加列表或其他对象。将列表这类对象作为 append()方法的参数时,append()方法将列表作为一个独立的元素追加到原列表中,从而形 成嵌套列表。 若要将追加的列表中的元素作为单独元素追加到原列表中,可以使用另一个增加列表 元素的方法extend(),示例代码如下。 【例5-15】 列表的extend()方法。 fruits = ['苹果','草莓','香蕉','梨', '百香果'] fruits. extend (['猕猴桃']) print(fruits) #输出['苹果', '草莓', '香蕉', '梨', '百香果', '猕猴桃'] fruits. extend (['西瓜','樱桃']) print(fruits) #输出['苹果', '草莓', '香蕉', '梨', '百香果', '猕猴桃', '西瓜', '樱桃'] 注意:fruits.extend(['猕猴桃'])不能写成fruits.extend('猕猴桃'),extend()方法将把 “猕猴桃”作为字符序列分别一一追加到fruits列表中,最终fruits列表会变成['苹果','草莓', '香蕉','梨','百香果','猕','猴','桃']。 若希望在列表中间增加新元素,可使用insert()方法。insert()方法有两个参数:第一 84 第5 章 列表、元组和字典 个参数指明插入位置;第二个参数是要增加的数据。看下面的示例。 【例5-16】 列表的insert()方法。 fruits = ['苹果','草莓','香蕉','梨', '百香果'] fruits. insert (2,'猕猴桃') print(fruits) # 输 出 [' 苹果', '草莓', '猕猴桃', '香蕉', '梨', '百香果'] fruits. insert (4,['西瓜','樱桃']) print(fruits) # 输 出 [' 苹果', '草莓', '猕猴桃', '香蕉', ['西瓜', '樱桃'], '梨', '百香果'] 5.1.5 查找列表元素 查找列表元素包括查找列表中的某个元素出现的位置,统计某个元素在列表中出现的 次数,检查某个元素是否存在于列表中等。下面的代码分别展示了上述各种查找列表元素 的方法。示例代码如下。 【例5-17】 查找列表元素示例。 #使用index()方法定位元素 list_a = [12,15,'a','b','c',15,9] print(list_a.index(12)) #0 print(list_a.index(15)) #1,定位第一个15 出现的位置 print(list_a.index(15,2)) #5,从索引2 开始定位15 出现的位置 print(list_a.index(15,2,4)) #在索引2 和索引4 之间定位15,返回ValueError 错误 #使用count()方法统计元素出现的次数 list_b = [12,15,'a','b','c',15,9] print(list_b.count(15)) #2 #使用in 运算符判断列表是否包含某个元素 list_c = [12,15,'a','b','c',15,9] print(12 in list_c) #True print(112 in list_c) #False print(112 not in list_c) #True 5.1.6 修改列表元素 可以通过给列表的元素赋值的方式修改列表元素。示例代码如下所示。 【例5-18】 修改列表元素示例1。 list_a = list(range(1,10)) print(list_a) #输出[1, 2, 3, 4, 5, 6, 7, 8, 9] list_a[1] = list_a[1]+1 print(list_a) #输出[1, 3, 3, 4, 5, 6, 7, 8, 9] 85 list_a[-1] = 100 print(list_a) #输出[1, 3, 3, 4, 5, 6, 7, 8, 100] list_a[:3] = ['a','b','c'] print(list_a) #输出['a', 'b', 'c', 4, 5, 6, 7, 8, 100] 利用切片功能对列表进行赋值时,并不要求新赋值的元素个数与切片的元素个数相同, 这表明可以利用这种方式实现在列表中增加元素或者删除元素的效果。示例代码如下。 【例5-19】 修改列表元素示例2。 list_b = list(range(1,10)) print(list_b) #输出[1, 2, 3, 4, 5, 6, 7, 8, 9] list_b[2:2]=['x','y','z'] print(list_b) #输出[1, 2, 'x', 'y', 'z', 3, 4, 5, 6, 7, 8, 9] list_b[-7:]=[] print(list_b) #输出[1, 2, 'x', 'y', 'z'] list_b[:2]=['x','y','z'] print(list_b) #输出['x', 'y', 'z', 'x', 'y', 'z'] 5.1.7 删除列表元素 删除列表中的元素可以使用del语句,此语句既可删除列表中的单个元素,也可删除列 表的中间一段元素。示例代码如下。 【例5-20】 删除列表元素示例1。 list_1 = ['I', 'am', 'very', 'happy'] del list_1[0] print(list_1) #输出['am', 'very', 'happy'] del list_1[1:2] print(list_1) #输出['am', 'happy'] list_2 = list(range(1,10)) del list_2[2:-2:2] print(list_2) #输出[1, 2, 4, 6, 8, 9] del list_2 #del 语句删除变量 print(list_2) list_2被del删除后,再用print输出时,弹出如图5-4所示的出错信息,说明list_2已不存在。 图5-4 对象不存在出错提示 86 第5 章 列表、元组和字典 在Python中还可以用列表的remove()方法删除与指定值能第一个匹配上的元素,示 例代码如下。 【例5-21】 列表的remove()方法。 list_1 = ['I', 'am', 'very', 'happy', 'very', 'happy'] list_1.remove('I') print(list_1) #输出['am', 'very', 'happy', 'very', 'happy'] list_1.remove('very') print(list_1) #输出['am', 'happy', 'very', 'happy'] Python中还提供了clear()方法,此方法用于清空列表。示例代码如下。 【例5-22】 列表的clear()方法。 list_1 = list_2 = list(range(1, 5)) list_1.clear() #清空list_1 print(list_1) #输出[] del list_2 #销毁list_2 print(list_2) #使用list_2 会报NameError:类型的错误 5.1.8 案例实现 本程序先显示水果店已有水果,再根据小明输入的水果对已有水果列表进行更新,若水 果店已有此水果,则仅更新该水果的质量,若水果店无此水果,则将该水果添加到已有水果 列表里。示例代码如下。 print("水果店已有水果:") fruits = [['苹果',100],['梨',120],['香蕉',150]] print(fruits) list1=[] a=len(fruits) for i in range(a): list1.append(fruits[i][0]) name = input("水果名:") weight = int(input("质量:")) print("更新后的水果列表:") if name in list1: index1=list1.index(name) fruits[index1][1]+=weight print(fruits) else: 87