第5章列表和元组 5.1知 识 要 点 5.1.1序列 Python中常用的序列结构有列表、元组、字典、集合、字符串等。从是否有序这个角度看,Python序列可以分为有序序列和无序序列,其中,列表、元组和字符串属于有序序列,而字典和集合属于无序序列; 从是否可变来看,Python序列则可以分为可变序列和不可变序列两大类。其中,列表、字典和集合属于可变序列,而元组和字符串属于不可变序列。列表、元组、字符串有序序列支持双向索引,第一个元素下标为0,第二个元素下标为1,以此类推; 如果使用负数作为索引,则最后一个元素下标为-1,倒数第二个元素下标为-2,以此类推。 5.1.2列表 1. 列表的创建和删除 1) 列表的创建 列表的创建可以使用list类的构造函数创建一个空列表,也可以使用“=”直接创建一个列表并赋值给其他变量,其格式如下。 格式1: 列表名=list() 格式2: 列表名=[元素1, 元素2, …, 元素n] 2) 列表的删除 当列表不用时可以使用del命令将其删除,其格式如下。 del 列表名 2. 列表元素的访问 在列表创建之后,就可以进行使用了。列表元素的使用可以使用下标法,其格式如下。 列表名[下标] 使用整数作为下标来访问列表的元素,下标从0开始,第一个元素是a_list[0],第2个元素是a_list[1],以此类推; 列表还支持使用负整数作为下标,其中,下标为-1的元素表示最后一个元素,下标为-2的元素表示倒数第2个元素,以此类推。 3. 列表的基本操作 列表、元组、字典、集合、字符串等序列有很多操作是通用的,而不同类型的序列又有一些特有的方法或者支持某些特有的运算符和内置函数。列表常用的操作如表51所示。 表51列表常用的操作 方法说明 append(x)将x追加至列表尾部 extend(L)将列表L中的所有元素追加至列表尾部 insert(index, x)在列表index位置处插入x remove(x)在列表中删除第一个值为x的元素 pop([index]) 删除并返回列表中下标为 index的元素,省略index时,删除最后一个元素 clear()清空列表,删除列表中的所有元素,保留列表对象 index(x)返回列表中第一个值为x的元素的索引 count(x)返回x在列表中的出现次数 reversed( )对列表所有元素进行原地逆序,首尾交换 sort(key=None. reverse=False) 对列表中的元素进行原地排序,key用来指定排序规则, reverse为False表示升序,为True表示降序 copy()返回列表的浅复制 4. 列表对象支持的运算符 1) 加法运算 加法运算符+和复合加法赋值+=用于将两个列表合并。需要注意的是,“+”运算不属于原地操作,而是返回一个新列表,效率比较低。“+=”运算属于原地操作,与append()方法一样高效。 2) 乘法运算 乘法运算符*用于列表和整数相乘,表示序列重复,不属于原地操作,返回新列表。复合乘法赋值*=也可用于列表元素的重复,与运算符+=一样也属于原地操作。 3) 成员测试运算符in 成员测试运算符in可用于测试列表中是否包含某个元素,结果是bool型。 5. 列表推导式 列表推导式的语法形式为: [expression for expr1 in sequence1 if condition1 for expr2 in sequence2 if condition2 for expr3 in sequence3 if condition3  for exprN in sequenceN if condtionN] 列表推导式在逻辑上等价于一个循环语句,只是形式上更加简洁。 6. 列表的切片操作 切片操作除了适用于列表之外,还适用于元组、字符串。切片使用两个冒号分隔的3个数字来完成,其格式如下。 [start: end: step] 其中,第一个数字start表示切片开始的位置,默认为0; 第二个数字end表示切片截止(但不包含)的位置,默认为列表长度; 第三个数字step表示切片的步长(默认为1)。当start为0时可以省略,当end为列表长度时可以省略,当step为1时可以省略,省略步长时还可以同时省略最后一个冒号。另外,当step为负整数时,表示反向切片,这时 start应该在end的右侧才行。 7. Python内置函数对列表的操作 通过内置函数可以对列表进行操作。例如,len( )、max( )、min( )可以获取列表的长度、列表中元素的最大值和最小值; sum( )可以获取列表或元组中元素之和; zip( )函数用于将多个列表中元素重新组合为元组并返回包含这些元组的zip对象; map()函数把函数映射到列表上的每个元素等。 5.1.3元组 1. 元组的创建、删除与元素访问 1) 元组的创建 在形式上,元组的所有元素放在一对圆括号中,元素之间使用逗号分隔,如果元组中只有一个元素则必须在最后增加一个逗号。元组的创建格式如下。 格式1: 元组名=tuple() 格式2: 元组名=(元素1, 元素2, … , 元素n) 2) 元组的删除 与列表的删除一样,当不再使用元组时,可以使用del命令将其删除,其格式如下。 del 元组名 3) 元组元素的访问 在元组创建之后,就可以进行使用了。元组元素的使用也是下标法,其格式如下。 元组名[下标] 元组也支持双向索引。元组属于不可变序列,不可以修改、添加、删除元素。 2. 元组与列表的异同点 1) 相同点 元组和列表都属于有序序列,都支持使用双向索引访问其中的元素。 2) 不同点 列表属于可变序列,而元组属于不可变序列。因此,元组没有append( )、extend( )、 insert( )等方法,也没有pop( )、remove( )方法,同时,元组也不支持对元素进行del操作,不能从元组中删除元素,而只能使用del删除整个元组。 元组也支持切片操作,但只能通过切片来访问元组中的元素,不能使用切片改变元组中的元素值。从一定程度上来说,元组是轻量级的列表。 Python的内部实现对元组做了大量优化,访问速度比列表快。 5.2例题分析与解答 一、 选择题 1. 下列哪种不是Python元组的定义方式? A. (1)B. (1, )C. (1, 2)D. (1, 2, (3, 4)) 分析: Python中规定,如果元组中只有一个元素,则必须在最后增加一个逗号,所以A选项的定义方式是错的。 答案: A 2. 下列代码执行结果是 。 [i**i for i in range(3)] A. [1, 1, 4]B. [0, 1, 4]C. [1, 2, 3]D. (1, 1, 4) 分析: **是Python的幂运算符,i**i 表示i的平方,[i**i for i in range(3)]是列表推导式,i的取值范围是0~2,即对0,1,2分别求平方,需要注意的是02=1,所以答案应该是A选项。 答案: A 3. Python语句 print(type([1,2,3,4])的输出结果是。 A. B. C. D. 分析: 内置函数type()用来查看变量的类型,很明显[1,2,3,4]是列表list,所以选D选项。 答案: D 4. Python语句 print(type((1,2,3,4))的输出结果是。 A. B. C. D. 分析: 内置函数type()用来查看变量的类型,很明显(1,2,3,4)是元组tuple,所以选A选项。 答案: A 5. Python语句 print(type({}))的输出结果是。 A. B. C. D. 分析: 内置函数type()用来查看变量的类型,花括号“{}”既可以是字典的定界符,也可以是集合的定界符,如果花括号内没有任何元素,则认为是一个空字典,所以选B选项。 答案: B 6. Python语句x=[1,2,3,None,(),[],]; print(len(x))的输出结果是。 A. 4B. 5C. 6D. 7 分析: 列表元素之间用逗号分隔,同时,一个列表也可以作为另一个列表的元素。需要注意的是,最后一个逗号后面并没有元素了(可省略),所以列表x中共有6个元素,因此选C选项。 答案: C 7. Python语句sl=[4,5,6];s2=s1;s1[1]=0; print(s2)的运行结果是。 A. [4,5,6]B. [0,5,6]C. [4,0,6]D. 以上都不对 分析: 在Python中的变量并不直接存储值,而是存储了值的内存地址或者引用,把一个列表变量赋值给另一个变量,这样两个变量指向同一个列表对象,对其中一个做任何修改都会立刻在另一个变量得到体现。该例中,s2=s1就是s2和s1引用同一块内存,s1[1]=0实际上s2[1]也变为0了,所以选C选项。 答案: C 8. 已知列表x=list(range(5)),那么执行语句x.remove(3) 之后,表达式x.index(4) 的值为。 A. 5B. 4C. 3D. 2 分析: x=list(range(5)),x=[0,1,2,3,4],执行语句x.remove(3),则x=[0,1,2,4],x.index(4)则是查找元素4在列表中的下标,很明显下标值为3(下标从0开始编号),所以选C选项。 答案: C 9. 已知列表x=[1, 3, 2],执行语句y=list(reversed(x)) 后,x的值为。 A. [3,2,1]B. [1,3,2]C. [1,2,3]D. [2,3,1] 分析: 内置函数reversed()返回一个逆序后的对象(不改变原来列表x的值),所以y的值为[2,3,1] ,而x并没有变化,因此选B选项。 答案: B 二、 填空题 1. 列表对象的方法删除首次出现的指定元素,如果列表中不存在要删除的元素,则抛出异常。 分析: remove(x)在列表中删除第一个值为x的元素,该元素之后的所有元素前移并且索引减1,如果列表中不存在x则抛出异常。 答案: remove( ) 2. 已知列表对象x=['11', '2', '3'],则表达式max(x, key=len) 的值为。 分析: 内置函数max(x)用来求对象x的最大值,这里x是列表,求的是列表元素的最大值,同时key=len表示指定了比较大小的规则是元素的长度(注意,列表x的元素是字符串,字符串长度就是字符的个数),长度最大的元素为'11'。 答案: '11' 3. 已知列表x=list(range(10)),那么执行语句del x[::2]之后,x的值为。 分析: x=list(range(10)),则x=[0,1,2,3,4,5,6,7,8,9],x[::2]是切片操作,等价于x[0:10:2],即从列表第一个元素开始,以步长为2(隔一个取一个),获得下标为偶数的元素,因此,del删除的是列表x中偶数位置的元素,删除后x=[1,3,5,7,9]。 答案: [1,3,5,7,9] 4. 假设列表对象aList的值为[3, 4, 5, 6, 7, 9, 11, 13, 15, 17],那么切片aList[3:7]得到的值是。 分析: aList[3:7],该切片操作没有第三个参数步长,取默认值1,将aList中从下标3开始到下标7(不包括)的元素依次获取组成新的列表[6,7,9,11]。 答案: [6,7,9,11] 5. 已知列表 x=[1.0, 2.0, 3.0],那么表达式 sum(x)/len(x) 的值为。 分析: sum()和len()都是内置函数,sum(x)求出列表x所有元素之和,为6.0,len(x)求出列表x的元素个数,为3,sum(x)/len(x)=6.0/3=2.0。 答案: 2.0 6. 已知列表 x=[1, 3, 2],那么执行语句 x.reverse() 之后,x的值为。 分析: 列表对象的reverse()方法对列表所有元素进行原地(即用处理后的数据替换原来的数据)逆序,首尾交换,因此x变为[2,3,1]。 答案: [2, 3, 1] 7. 已知列表x=[1, 2],那么执行语句x.extend([3,4]) 之后, x的值为。 分析: 列表对象的extend()方法将其参数(也是列表)的所有元素追加至原列表的尾部,因此,x变为[1,2,3,4]。 答案: [1,2,3,4] 8. 已知列表 x=[1, 2, 3],那么执行语句 x.insert(1, 4) 之后,x的值为。 分析: x.insert(1,4)表示在列表x的下标为1的位置插入新的元素4,原下标位置1后面的元素依次后移,因此x变为[1,4,2,3]。 答案: [1,4,2,3] 9. 使用列表推导式生成包含10个数字5的列表,语句可以写为。 分析: 只需要循环生成10次5即可用生成包含10个数字5的列表,可以写成[5 for i in range(10)]。 答案: [5 for i in range(10)] 10. aList=[-2, 1, 3, -6],如何实现以绝对值大小从小到大将aList 中内容排序。 分析: 列表的排序可以调用其sort()方法,sort()方法排序时可以指定排序的关键字为求绝对值abs,此语句可写成aList.sort(key=abs)。 答案: aList.sort(key=abs) 5.3测试题 一、 选择题 1. 已知x=[1, 2]和y=[3, 4],那么x+y的结果是。 A. 3B. 7C. [1, 2, 3, 4]D. [4, 6] 2. 已知x=[1, 2, 3],那么x*3的值为。 A. 6B. [1, 6, 9] C. [3, 6, 9]D. [1, 2, 3, 1, 2, 3, 1, 2, 3] 3. 已知x=[1, 2, 3],执行语句x.append(4)之后,x的值是。 A. [1, 2, 3, 4]B. [4]C. [1, 2, 3]D. 4 4. 已知x=[1, 2, 3, 4, 5, 6, 7],那么x.pop()的结果是。 A. 1B. 4C. 7D. 5 5. sum([i*i for i in range(3)])的计算结果是。 A. 3B. 5C. 2D. 14 6. 下面代码输出结果为。 #1. x=[3] #2. L=[3,2,1] #3. for i in range(x[0]): #4.L.append(i*i) #5. print(L) A. [3, 2, 1, 0, 1, 4]B. [3,2,1,1,4,9] C. [0,1,4]D. [1,4,9] 7. 已知列表x=[1, 2],那么连续执行命令y=x和y.append(3)之后,x的值为。 A. [1,2]B. [1,2,3]C. [3,1,2]D. 不确定 8. 已知列表x=[1, 3, 2],那么执行语句a,b,c=sorted(x) 之后,b的值为。 A. 1B. 2C. 3D. 不确定 9. 已知列表 x=[1, 2],那么执行语句 x.append([3]) 之后,x的值为。 A. [1,2,3]B. [1,2]C. [3,1,2]D. [1,2,[3]] 10. 已知列表 x=[1, 3, 2],那么执行语句 x=x.reverse() 之后,x的值为。 A. NoneB. [2,3,1]C. [1,3,2]D. [1,2,3] 11. 列表变量ls共包含10个元素,1s索引的取值范围是。 A. -1~-9(含)的整数B. 0~10(含)的整数 C. 1~10(含)的整数D. 0~9(含)的整数 12. 以下不是Python复合数据类型的是。 A. 字符串类型B. 数组类型C. 列表类型D. 元组类型 13. 对于列表s,能够返回列表s中第i~j且以k为步长的子列表的表达式是。 A. s[i:j:k]B. s[i,j,k]C. s[i;j;k]D. s(i,j,k) 14. 对于序列s,以下选项对min(s)描述正确的是。 A. 一定能够返回序列s中的最小元素 B. 可以返回序列s中的最小元素,但要求s中元素可比较 C. 可以返回序列s中的最小元素,如果存在多个相同的最小元素,则返回一个元组类型 D. 可以返回序列s中的最小元素,如果存在多个相同的最小元素,则返回一个列表类型 15. 以下程序输出的结果是。 #1.ls=[1,2,3] #2.lt=[4,5,6] #3.print(ls+lt) A. [5,7,9]B. [1,2,3,[4,5,6]] C. [1,2,3,4,5,6]D. [4,5,6] 16. 以下程序输出的结果是。 #1.a=[3,2,1] #2.for i in a[::-1]: #3.print(i, end=' ') A. 1,2,3B. 3 2 1C. 1 2 3D. 3,2,1 17. 以下程序的输出结果是。 #1.a=[3,2,1] #2.b=a[:] #3.print(b) A. [3,2,1]B. [ ]C. [1,2,3]D. 0xA1F8 18. 以下关于 Python列表的描述中,错误的是。 A. 列表的长度和内容都可以改变,但元素类型必须相同 B. 可以对列表进行成员关系操作、长度计算和切片 C. 列表可以同时使用正向递増序号和反向递减序号进行索引 D. 可以使用比较操作符(如>或<等)对列表进行比较 19. 以下用来处理Python列表的方法中,错误的是。 A. interleaveB. appendC. insertD. remove 20. 以下代码的输出结果是。 #1.ls=[ 'book ', 23, [2010, 'stud1'], 20] #2.print(ls[2][1][-1]) A. sB. stud1C. 1D. 结果错误 21. 以下代码的输出结果是。 #1.a=[[1,2,3], [4,5,6], [7,8,9]] #2.s=0 #3.for c in a: #4.for j in range(3): #5.s+=c[j] #6.print(s) A. 6B. 0C. 24D. 45 22. 以下代码的输出结果是。 #1.vlist=list(range(5)) #2.print(vlist) A. 0; 1; 2; 3; 4;B. 0 1 2 3 4 C. 0, 1, 2, 3, 4D. [0, 1, 2, 3, 4] 23. 以下关于列表变量ls操作描述中,错误的是。 A. ls.reverse(): 反转列表ls中的所有元素 B. ls.clear(): 删除ls的最后一个元素 C. ls.copy(): 生成一个新列表,复制ls的所有元素 D. ls.append(x): 在ls最后增加一个元素 24. 列表listV=list(range(10)),以下能够输出列表listV中最大元素的是。 A. print(listV.reverse(i)[0])B. print(listV.max()) C. print(max(listV()))D. print(max(listV)) 25. 以下代码的输出结果是。 #1.ls=[] #2.for m in 'AB': #3.for n in 'CD ': #4.ls.append(m+n) #5.print(ls) A. ABCDB. AABBCCDD C. ACADBCBDD. ['AC ', 'AD ', 'BC', 'BD'] 26. 以下描述中,错误的是。 A. Python语言通过索引来访问列表中元素,索引可以是负整数 B. 列表用方括号来定义,继承了序列类型的属性和方法 C. Python列表是各种类型数据的集合,列表中的元素不能够被修改 D. Python语言的列表类型能够包含其他的组合数据类型 27. 以下代码的输出结果是。 #1.s=[4, 2, 9, 1] #2.s.insert(2, 3) #3.print(s) A. [4, 2, 9, 2, 1]B. [4, 3, 2, 9, 1] C. [4, 2, 3, 9, 1]D. [4, 2, 9, 1, 3] 28. 以下代码的输出结果是。 #1.ls=[[1, 2,3], [[4, 5], 6], [7, 8]] #2.print(len(ls)) A. 3B. 1C. 4D. 8 29. 以下代码的输出结果是。 #1.ls=["2020", "20.20", "Python"] #2.ls.append(2020) #3.ls.append([2020, "2020"]) #4.print(ls) A. ['2020', '20.20', 'Python', 2020] B. ['2020', '20.20', 'Python', 2020, [2020, '2020']] C. ['2020', '20.20', 'Python', 2020, 2020, '2020'] D. ['2020', '20.20', 'Python', 2020, ['2020']] 30. 以下代码的输出结果是。 #1.l1=["aa", [2, 3, 3.0]] #2.print(l1.index(2)) A. 2B. 3.0C. 3D. ValueError 31. 以下程序的输出结果是。 #1.ls1=[1, 2, 3, 4, 5] #2.ls2=ls1 #3.ls2.reverse() #4.print(ls1) A. [5, 4, 3, 2, 1]B. [1, 2, 3, 4, 5] C. 5, 4, 3, 2, 1D. 1, 2, 3, 4, 5 32. 以下程序的输出结果是。 #1.ls=[12, 44, 23, 46] #2.for i in ls: #3.if i=='44': #4.print('found it! i=' ,i) #5.break #6.else: #7.print('not found it…') A. not found it…B. found it! i=44 C. found it! i=44 not found it… D. found it! i='44' not found it… 33. 以下程序的输出结果是。 #1.L1=[1, 2, 3, 4] #2.L2=L1.copy() #3.L2.reverse() #4.print(L1) A. 1, 2, 3, 4B. [4, 3, 2, 1] C. 4, 3, 2, 1D. [1, 2, 3, 4] 34. 以下程序的输出结果不可能的选项是。 #1.import random #2.ls=[2, 3, 4, 6] #3.s=10 #4.k=random.randint(0,2) #5.s+=ls[k] #6.print(s) A. 12B. 14C. 13D. 16 35. 以下程序的输出结果是。 #1.ls=['绿茶', '乌龙茶', '红茶', '白茶', '黑茶'] #2.x='乌龙茶' #3.print(ls.index(x,0)) A. 0B. 1C. -3D. -4 36. 二维列表ls=[[9, 8], [7, 6], [5, 4], [3, 2], [1, 0]],能够获得数字4的选项是。 A. ls[-2,0]B. ls[3,2]C. ls[2,2]D. ls[-3,-1] 37. 以下程序的输出结果是。 #1.lt=['绿茶', '乌龙茶', '红茶', '白茶', '黑茶'] #2.ls=lt #3.ls.clear() #4.print(lt) A. 变量未定义的错误 B. [] C. ['绿茶', '乌龙茶', '红茶', '白茶', '黑茶'] D. '绿茶', '乌龙茶', '红茶', '白茶', '黑茶' 二、 填空题 1. 列表对象的sort()方法用来对列表元素进行原地排序,该方法的返回值为。 2. 表达式“[3] in [1,2,3,4]”的值为。 3. 表达式list(range(1, 10, 3))的值为。 4. 已知列表对象x=['15', '25', '3'],则表达式 max(x) 的值为。 5. 已知列表x中包含超过5个以上的元素,那么表达式 x == x[:5]+x[5:] 的值为。 6. 已知列表 x=[1, 2, 3],那么表达式 [value for index, value in enumerate(x) if index==2] 的值为。 7. 已知列表 x=[1, 3, 2],那么执行语句 y=list(reversed(x)) 之后,y的值为。 8. 已知列表 x=[1, 3, 2],那么执行语句 a, b, c=map(str, sorted(x)) 之后,c的值为。 9. 已知列表 x=[1, 2],那么连续执行命令 y=x[:] 和 y.append(3) 之后,x的值为。 10. (可以、不可以)使用del命令来删除元组中的部分元素。 11. 已知列表 x=[1, 2, 3],那么执行语句 x.pop(0) 之后,x的值为。 12. 假设有一个列表a,现要求从列表a中每3个元素取1个,并且将取到的元素组成新的列表b,可以使用语句。 13. 已知 x=(2,),那么表达式 x * 3 的值为。 14. 已知列表 x=[1, 2, 3],那么表达式 list(enumerate(x)) 的值为。 15. 写一行代码实现对列表a中的偶数位置的元素进行加3后求和,可以写成。 16. 表达式 [i for i in range(10) if i>8] 的值为。 17. 表达式 [5 for i in range(3)] 的值为。 18. 表达式 [1, 2, 3].count(4) 的值为。 19. 假设列表对象aList的值为[3, 4, 5, 6, 7, 9, 11, 13, 15, 17],那么切片aList[3:7]得到的值是。 20. 已知 x=[3, 7, 5],那么执行语句 x.sort(reverse=True)之后,x的值为。 21. 已知 x=[3, 5, 7],那么表达式 x[10:]的值为。 22. 已知 x=[3, 5, 7],那么执行语句 x[:3]=[2]之后,x的值为。 23. 已知 x=[1, 2, 3, 4, 5],那么执行语句 del x[1:3] 之后,x的值为。 24. 已知 x=[1, 2, 1],那么表达式 id(x[0]) == id(x[2]) 的值为。 25. 表达式 [index for index, value in enumerate([3,5,7,3,7]) if value == max([3,5,7,3,7])] 的值为。 三、 编程题 1. 编写程序,求列表中的元素个数,最大值、最小值、元素之和、平均值,并请思考,有哪几种实现方法?至少用两种方法实现。 2. 用户输入若干个分数存放到列表中,求所有分数的平均分。每输入一个分数后询问是否继续输入下一个分数,回答“yes”就继续输入下一个分数,回答“no”就停止输入分数。 3. 将一个列表中的元素为奇数的放到前面,偶数放到后面,并输出。 4. 编写程序,生成20个0~100随机数的列表,然后将列表中的奇数放到列表的前面,偶数放到后面,且奇数和偶数都要按升序存放,统计奇数和偶数的个数,并输出结果。 5. 统计1900—2019年中有多少闰年(使用列表推导式)。 6. 有一个4行4列的矩阵,求出其转置矩阵。 7. 将一个4行4列的矩阵逆时针旋转90°。 8. 猴子吃桃问题: 猴子第一天摘下若干个桃子,当天吃了一半,还不过瘾,又多吃了一个。第二天早上又将剩下的桃子吃掉一半,又多吃了一个。以后每天早上都吃了前一天剩下的一半加一个。到第十天早上再想吃时,发现就只剩一个桃子了。求第一天共摘了多少个桃子? 9. 编写程序,接收一个数字的列表; 计算得到一个新的列表,其中,第i个元素是原列表的前i个元素的和。例如,原列表x=[1,2,3,4,5],则新列表为[1,3,6,10,15]。 10. 在歌星大奖赛中,有10个评委为参赛的选手打分,分数为1~100分。选手最后得分为: 去掉一个最高分和一个最低分后其余8个分数的平均值。请编写一个程序实现。 5.4实 验 案 例 一、 输出列表的子列表 1. 实验要求 用户输入一个列表和两个整数作为下标,然后输出列表中介于两个下标之间的元素组成的子列表。例如,用户输入[1,2,3,4,5,6]和2,5,程序输出[3,4,5,6]。编写并输入代码,保存到程序文件Ex51.py中,运行程序并观察结果。 2. 算法分析 使用列表的切片操作即可求出子列表。 3. 完善程序 #1.x = input('Please input a list:') #2.x = eval(x) #3.start, end = eval(input('Please input the start position and the end position:')) #4.print() 4. 调试程序 保存文件为Ex51.py,运行程序,程序输出结果如下。 Please input a list:[1,2,3,4,5,6] Please input the start position and the end position:2,5 [3, 4, 5, 6] 二、 序列元素排序 1. 实验要求 生成包含20个随机数的列表,然后将前10个元素升序排列,后10个元素降序排列,并输出结果。编写并输入代码,保存到程序文件Ex52.py中,运行程序并观察结果。 2. 算法分析 使用内置函数sorted()可对列表排序。 3. 完善程序 #1.import random #2.#随机生成20个范围在[0,100]的随机数 #3.x = [random.randint(0,100) for i in range(20)] #4.print(x)#输出排序前的列表 #5.x[:10] = #6. = sorted(x[10:], reverse=True) #7.print(x) #输出排序后的列表 三、 删除指定的元素 1. 实验要求 生成一个包含50个随机整数的列表,然后删除其中所有偶数。编写并输入代码,保存到程序文件Ex53.py中,运行程序并观察结果。 2. 算法分析 循环遍历列表元素,判断为偶数则将其删除。 3. 完善程序 #1.import random #2.x = [random.randint(0,100) for i in range(50)] #3.print(x) #4.for i in range(len(x))[::-1]:#从后往前遍历 #5.if : #6.del x[i] #7.print(x) 四、 部分元素排序 1. 实验要求 生成一个包含20个随机整数的列表,然后对其中偶数下标的元素进行降序排列,奇数下标的元素不变。编写并输入代码,保存到程序文件Ex54.py中,运行程序并观察结果。 2. 算法分析 使用切片完成,切片的步长为2。 3. 完善程序 #1.import random #2.x = [random.randint(0,100) for i in range(20)] #3.print(x) #4.x[::2] = sorted() #5.print(x) 五、 整数的因式分解 1. 实验要求 用户从键盘输入小于1000的整数,对其进行因式分解。例如,10=2×5,60=2×2×3×5。编写并输入代码,保存到程序文件Ex55.py中,运行程序并观察结果。 2. 算法分析 对于一个整数x,从i(i初始值为2)开始判断,如果x能被2整除,则认为2是一个有效因子,将其保存在列表中,然后x的值变为x//2,如果x不能被2整除,则开始从下一个数i+1判断。如此反复,直到最后x值变为1,保存在列表中的所有数相乘就是因式分解的结果,其流程图如图51所示。 图51因式分解 3. 完善程序 #1.x = input('Please input an integer less than 1000:') #2.x = eval(x) #3.t = x #4.i = 2 #5.result = [] #该列表用于存放x的所有因子 #6.while : #7.if t%i == 0: #8. #9.t = #10.else: #11. #12.print(x,'=',end='') #13.for i in range(len(result)):#输出因式分解的结果 #14. if #15. print(result[i],end='') #16. else: #17. print(result[i],'*',end='') 六、 删除重复元素 1. 实验要求 将列表中的重复元素去除,例如,列表内容为[1,2,3,1,5,3,7],去除重复元素后列表内容为[1,2,3,5,7]。编写并输入代码,分别保存到程序文件Ex561.py和Ex562.py中,运行程序并观察结果。 2. 完善程序 方法一: #1.l=[1,2,3,1,5,3,7]#将本方法代码存入程序文件Ex5-6-1.py #2.L=[] #3.for i in l: #4.if i not in L: #5. #6.print(L) 方法二: 使用集合(第6章会学到集合) #1.l=[1,2,3,1,5,3,7]#将本方法代码存入程序文件Ex5-6-2.py #2.list(set(l)) #直接将列表转换为集合,再转换为列表 七、 插入排序法 1. 实验要求 不使用内置函数和列表sort()方法的前提下,使用插入排序法对列表中元素排序。编写并输入代码,保存到程序文件Ex57.py中,运行程序并观察结果。 2. 算法分析 插入排序是最常见的数据排序方法之一,它的基本原理就是将一个数据插入到一组已经排好序的序列当中,插入后该序列依旧是有序的。 算法思想(从小到大排序): (1) 一组数据(包含N个元素的列表x),设置变量i,j,temp,i是待插入元素的下标,将x[i]赋值给temp,j用来搜索比较。 (2) i的初始值为1,即从第二个元素开始,只有一个元素的列表直接被认为是已经排好序的,所以从第二个元素开始,j的初始值为i-1。 (3) 将i之前的数据都与temp比较,即与待插入数据进行比较,用 j 来移动下标,每次j=j-1,直到找到一个比temp小的或等于的值,亦或找到了该序列的尽头(即下标为0)停止,将temp放到j+1的位置,即将待插入的数据插入到j+1的位置,该待插入数据就已经插入到了正确的位置。 (4) 然后将i=2,从第三个元素开始,j=i-1,执行temp=a[i],重复步骤3,直到 i==N-1停止,即所有数据都已经放到了正确的位置上,该序列即为一个有序序列。 例如,“17、13、9、12、5”的排序过程如表52所示。 表52插入排序过程示例 原始数据17139125 第一轮13179125 第二轮91317125 第三轮91213175 第四轮59121317 3. 完善程序 #1.x = input('Please input a list:') #2.x=eval(x) #3.n=len(x) #4.print("排序前: ",x) #5.for i in range(1,n):#外循环(1~n-1) #6.if : #7.temp=x[i] #8.j=i-1 #9.while :#内循环,元素后移 #10.x[j+1]=x[j] #11.j-=1 #12. #13.print("\n排序后: ",x) 八、 选择排序 1. 实验要求 不使用内置函数和列表sort()方法的前提下,使用选择排序法对列表中元素排序。编写并输入代码,保存到程序文件Ex58.py中,运行程序并观察结果。 2. 算法分析 选择法排序的思路是: 将n个数依次比较,保存最大数的下标位置,然后将最大数和第1个列表元素换位; 接着再将n-1个数依次比较,保存次大数的下标位置,然后将次大数和第2个列表元素换位; 接着再将n-2个数依次比较,保存第3大数的下标位置,然后将第3大数和第3个列表元素换位。按此规律,直至比较换位完毕。 例如,“2、3、9、6、5”的排序过程示意如下。 第1步: [23965]5个数比较,保存最大数9的下标位置2,将9和第1个数组元素2换位。 第2步: 9[3265]余下4个数比较,保存次大数6的下标位置3,将6和第2个数组元素3换位。 第3步: 96[235]余下3个数比较,保存第3大数5的下标位置4,将5和第3个数组元素2换位。 第4步: 965[32]最后两个数比较,不换位。 至此,排序完成。 3. 完善程序 #1.x = input('Please input a list:') #2.x=eval(x) #3.n=len(x) #4.for j in range(n):#外循环(0~n-1) #5. max1=x[j] #6. label=j #当前位置下标 #7. for i in range(j+1,n): #内循环,查找最大值下标 #8. if : #9. max1=x[i] #10. #11. t=x[label] #元素交换 #12. #13. x[j]=t #14.print('排序结果: ', x) 九、 序列处理 1. 实验要求 输入三个正数序列,从三个序列中各取一个值相乘,输出乘积最大的三个数及各序列中所取数的位置。例如,输入的三个序列为[2,3,1], [4,6,3], [5,2,4],最大值为3×6×5,下标1,1,0组合,第一个序列第二个,第二个序列第二个,第三个序列第一个。编写并输入代码,保存到程序文件Ex59.py中,运行程序并观察结果。 2. 算法分析 分别取出三个序列的最大元素,相乘的结果即为最大值,同时记录下所取元素在各自序列中的下标即可。 3. 完善程序 #1.x=input('Please input a list:') #2.x=eval(x) #3.y=input('Please input a list:') #4.y=eval(y) #5.z=input('Please input a list:') #6.z=eval(z) #7.i = #8.iPos = #9.j = max(y)#列表y的最大值 #10.jPos = y.index(j) #最大值所在的下标 #11.k = max(z) #12.kPos = z.index(k) #13.result= #14.print(result, (iPos, jPos, kPos)) 4. 思考题 如果序列中包括负数,程序需要调整吗?为什么?如果需要调整,应该怎么改动? 十、 水仙花数 1. 实验要求 水仙花数是指1个3位的十进制数,其各位数字的立方和等于该数本身。例如,153是水仙花数,因为153=13 + 53 + 33 。编写并输入代码,保存到相应程序文件中,运行程序并观察结果。 2. 算法分析 方法很多,例如: (1) 第4章介绍过用“穷举法”分别搜索100~999满足条件的值,采用算术运算符求出个位、十位、百位。 (2) 可以使用Python内置函数divmod()依次求出个位、十位、百位。 (3) 可以使用序列解包。 (4) 可以使用lambda表达式。 3. 完善程序 # 参考代码一,算术运算符。代码保存到程序文件Ex5101.py中。 #1.for num in range(100, 1000): #2.bai = num // 100#百位 #3.shi = #十位 #4.ge = num % 10 #个位 #5.if : #判断是否水仙花数 #6.print(num) # 参考代码二,内置函数。代码保存到程序文件Ex5102.py中。 #1.for num in range(100, 1000): #2.bai, rest = divmod(num, 100)#百位及余数 #3.shi, ge = #4.if ge**3 + shi**3 + bai**3 == num: #5.print(num) # 参考代码三,序列解包。代码保存到程序文件Ex5103.py中。 #1.for num in range(100, 1000): #2.bai, shi, ge = map() #3.if ge**3 + shi**3 + bai**3 == num: #4.print(num) # 参考代码四,lambda表达式。代码保存到程序文件Ex5104.py中。 #1.for num in range(100, 1000): #2.r = map() #3.if sum(r) == num: #4.print(num) 十一、 查找特定元素 1. 实验要求 随机生成一个列表,查找列表元素中最大值的所有出现和首次出现位置。例如,[23,45,28,56,45,56,32,11,21,10],其最大值为56,出现的位置有3和5,首次出现的位置是3。编写并输入代码,保存到程序文件Ex511.py中,运行程序并观察结果。 2. 算法分析 可以利用内置函数max求出列表元素的最大值,再遍历列表元素,将所有值等于该最大值的元素下标记录到另一个列表中。 3. 完善程序 #1.import random #2.randomNums=[random.randrange(30) for i in range(10)] #3.m=max(randomNums)#最大值 #4.listPos=[] #listPos用于存放m在列表中出现的所有位置下标 #5.length= #6.for i in range(length): #7. if(randomNums[i]==m): #8. #9.print("序列: ", randomNums) #10.print("最大值为: ", m) #11.print("序列中出现该最大值的位置有: ", listPos) #12.print("其中,首次出现的位置为: ", listPos[0]) 十二、 约瑟夫问题 1. 实验要求 给10个学生编号1~10,按顺序围成一圈,按1~3报数,凡报到3者出列,然后下一个人继续从1开始报数,直到最后只剩下一个人,计算剩下这个人是第几号学生并输出。编写并输入代码,保存到程序文件Ex512.py中,运行程序并观察结果。 2. 算法分析 定义一个学生编号的列表listNo,里面存放10个值都为1的元素,列表元素的下标即表示学生的编号,例如,下标0表示的是1号同学,下标1表示的是2号同学,……,下标9表示的是10号同学。报数的过程就是将列表中对应的元素相加的过程,当加到和为3时,说明该同学应该出列,则将该元素值变为0,同时将学生总数减去1,直到最后学生总数为1为止。 3. 完善程序 #1.num=int(input("请输入学生总数: ")) #2.listNo=[] #3.j=0 #4.for i in range(num): #5. listNo.append(1)#将列表元素全部初始化为1 #6.sum1=0 #7.while True: #8. sum1+=listNo[j] #9. if : #10.listNo[j]=0 #表示下标为j的同学出列 #11.sum1=0 #重新报数,累加结果 #12.#print(listNo) #跟踪测试,观察中间有同学出列后列表变化情况 #13.num-=1 #有同学出列,num-1 #14.if : #循环强行结束 #15.break #16. #17. if j>=len(listNo): #到达列表最后的元素后,重新回到列表开头 #18. #19.for i in range(len(listNo)): #20. if : #21.print("最后剩下的同学是: ",i+1,"号!") #22.break;