【例6-1】编写程序,接收一个数字的列表;计算得到一个新的列表,其中第i个元素是原先列表的前i个元素的积(第一个元素不变)。例如输入:[1,2,3,4,5],得到[1, 2, 6, 24, 120]
算法分析:从a=[1,2,3,4,5]得到b=[1,2,6,24,120],必须两重循环完成
外循环可以考虑根据列表a的长度进行,内循环则始终0开始,循环到外循环的位置
内循环里计算累乘
a = eval(input('Please input a list:'))
b = [ ]
for i in range(0, len(a)):
# 外循环实际上是得到新列表元素长度的循环
s = 1
# 每次内循环开始前,s初始化为1,为计算下一个元素的值做准备
for j in range(i + 1):
# 内循环是得到每个新元素的值
s *= a[ j ]
b.append(s)
print(b)
# 方法二-------------------------------------------------------------------------------------
a = eval(input('Please input a list:'))
j = 1
b = [ ]
for i in range(len(a)):
j *= a[ i ]
b.append(j)
print(b)
【例6-2】编写程序,通过循环模拟列表的reverse()方法。
# 方法一:将列表按照数组方式进行首尾互换
a = input('Please input a list:')
a = eval(a)
n = len(a)
i = 0
while i <= n // 2: # 按列表长度的整除2循环
t = a[i] # 将a中的元素依次首尾对调
a[i] = a[n - 1 - i]
a[n - 1 - i] = t
i = i + 1
print(a)
## 方法二
a = [1, 2, 6, 24, 120, 720, 5040]
a = eval(a)
n = len(a)
for i in range(n//2):
a[i] , a[n - 1 - i] = a[n - 1 - i] , a[i]
print(a)
# 方法三:按列表逆序循环,依次加入新列表中
a = [1, 2, 6, 24, 120, 720, 5040]
b = [ ]
for i in range(len(a)-1,-1,-1):
b.append(a[i])
a = b
print(b)
# 方法四
a=[1,2,3,4,5,6]
b=[ ]
for i in range(len(a)):
b.append(a.pop())
print(b)
【例6-3】编写程序,模拟列表的insert()方法。
#方法一:将要插入的元素到最后一个元素往后移动一位,为了元素不被覆盖,必须从后往前循环
a = eval(input('请输入一个列表:'))
index = eval(input('请输入要插入的下标位置:'))
value = eval(input('请输入要插入的元素:'))
if index >= len(a):
a.append(value) # 插入列表尾部
else:
a.append(None) # 先在列表尾部添加一个空元素
for i in range(len(a)-1,index-1,-1): # 将下标index及之后的元素依次后移一位
a[i] = a[i - 1]
a[index] = value # 插入元素value
print(a)
#方法二:同上,改用while循环
a = eval(input('请输入一个列表:'))
n = len(a)
index = eval(input('请输入要插入的下标位置:'))
value = eval(input('请输入要插入的元素:'))
if index >= n:
a.append(value) # 插入列表尾部
else:
a.append([ ]) # 先在列表尾部添加一个元素
m = n
while m > index: # 将下标index及之后的元素依次后移一位
a[m] = a[m - 1]
m -= 1
a[index] = value # 插入元素value
print(a)
【例6-4】编写程序,模拟列表的sort()方法。
#利用选择排序法给列表排序
import random
a=[ ]
for i in range(1,11):
a.append(random.randint(1,100))
else:
print(a) #初始化列表为10个1-100之间的元素
for i in range(0,9): #i=0,1,2…..8代表循环九轮
for j in range(i+1,10):
if a[i] > a[j]: #从小到大排序
a[i],a[j] = a[j],a[i]
print(a)
#利用冒泡法排序给列表排序
import random
a=[ ]
for i in range(1,11):
a.append(random.randint(1,100))
else:
print(a) #初始化列表为10个1-100之间的元素
for i in range(0,9): #i=0,1,2…..8代表循环九轮
for j in range(0,9-i):
if a[j]>a[j+1]: #从小到大排序
a[j],a[j+1]=a[j+1],a[j]
print(a)
【例6-5】编写程序,求出给定列表中相差最小的两个数字。
算法分析:先将列表从大到小排序,然后初始化相邻两数变量和其差的变量,最后循环判断相邻两数差是否为最小
a = [2,6,10,30,20,15,32] # eval(input('请输入一个列表:'))
a.sort(reverse=True) # 首先对这组数进行从大到小的排序
# print(a) # 输出降序排序结果
num1 = a[0]
num2 = a[1]
diff = num1 - num2 # 前两个数的差值
for i in range(1, len(a) - 1): # 从第2个元素开始计算差值
if a[i] - a[i + 1] < diff: # 差值小于diff的值时, 更新最小值以及num1和num2
diff = a[i] - a[i + 1]
num1 = a[i]
num2 = a[i + 1]
print('差值最小的两个数为:', (num1, num2))
# 方法二按照选择循环的方式进行两两相减比较,因为选择排序法任意两个数都会相见
a = [2,6,10,30,20,15,32]
num1 = a[0]
num2 = a[1]
diff = abs(num1 - num2) # 前两个数的差值
for i in range(len(a)-1):
for j in range(i+1,len(a)):
if abs(a[i] - a[j]) < diff: # 差值小于diff的值时, 更新最小值以及num1和num2
diff = abs(a[i] - a[j])
num1 = a[i]
num2 = a[j]
print('差值最小的两个数为:', (num1, num2))
【例6-6】编写程序,实现矩阵的转置功能。
'''
方法一算法分析:二维数组的转置即行变列,列变行,
观察后发现以主对角线为对称轴进行交换即可,
对称元素下标的关系为: [ i ][ j ]和[ j ][ i ]
'''
a = [ [1,2,3],
[4,5,6],
[7,8,9] ]
print('转置前:')
for i in range(len(a)):
print(a[i])
for i in range(len(a)): # 按矩阵的下三角形循环,可测试打印的数据分析
for j in range(0, i): # for j in range(0, i+1)也可以,顶点元素和自己交换
a[i][j] , a[j][i] = a[j][i] , a[i][j]
print('转置后:')
for i in range(len(a)):
print(a[i])
# 按矩阵的上三角形循环,可测试打印的数据分析
for j in range(len(a)):
for i in range(0, j+1):
print(a[i][j])
# 方法二:利用列表推导式
[[row[i] for row in a] for i in range(3)]
【例6-7】编写程序,生成具有20个元素值互不相等的列表,并给定一个整数n,以n为界,然后将列表中的小于n的元素全部放到列表前面,大于n的元素放到列表后面。
算法分析:产生20个不相等的数放入列表a,对a进行循环,
将a中元素小于等于n的数插入到列表b的头部,将a中元素大于n的数最加到b的尾部
import random
a = list(range(20))
random.shuffle(a)
# 洗牌,将列表a中元素随机打乱
print(a)
n = eval(input('请输入一个整数[0, 20):'))
b = [ ]
i = 0
while i < len(a):
if a[i] > n:
# 将大于n的元素插入b的首部
b.append(a[i])
else:
b.insert(0,a[i])
# 将小于n的元素插入b的首部
i += 1
print(b)
# 思考:以n为界,将列表中的小于n的元素以降序形式全部放到列表前面,大于n的元素以升序形式放到n的后面
# 方法二:利用列表推导式
import random
a = list(range(20))
random.shuffle(a) # 将列表a中元素随机打乱
print(a)
b = [ ]
n = eval(input('请输入一个整数[0, 20):'))
[ b.insert(0,a[i]) if a[i] <= n else b.append(a[i]) for i in range(len(a)) ]
print(b)
【例6-8】编写程序,删除列表中所有重复的元素。例如,有个列表a = [1, 2, 1, 1, 2],将a中重复出现的元素1删除后变为[ 1, 2 ]。
算法分析:
'''#方法一:用内置函数 #print(list(set(temLst))) #一行代码解决 但顺序变了
temLst = [1,3,53,6,7,35,63,6,6,4,7,5,6,7,34]
temSet = set(temLst)
temLst2 = list(temSet)
temLst2.sort(key = temLst.index) #解决顺序问题
print(temLst2,'temp2按key排序后:')
#方法二重点掌握: 遍历去除重复(通过追加到新的lst时,先判重)
temLst = [1,3,53,6,7,35,63,6,6,4,7,5,6,7,34]
List2 = [ ]
for i in temLst: #注意这里不是用i in range(n)
if not i in List2:
List2.append(i)
print(List2,'list2')
# 方法三:列表推导式
temLst = [1,3,53,6,7,35,63,6,6,4,7,5,6,7,34]
List2 = [ ]
[List2.append(i) for i in temLst if not i in List2]
print(List2,'列表推导式')
【例6-9】在有序序列中增加数据,使之仍保持有序(不使用列表的insert()方法)。
算法分析:和按下标插入类似,只不过循环判断要插,找到要插入的位置后,再循环后移,腾出空间后插入
a = eval(input('请输入有序(升序)列表:'))
# print('有序列表为:', a)
# 测试语句,可输出查看列表元素
n = len(a)
v = eval(input('请输入要插入的数:'))
a.append(v)
# 先将v加入到a的尾部,目的是增加一个空间
for i in range(n):
if v < a[i]:
# 找到列表中第一个大于v的元素,下标为i
for j in range(n, i, -1):
#将下标从n开始,到下标为i的元素依次后移
a[j] = a[j - 1]
a[i] = v
# 将v放到位置i处
break
print('插入后的列表为:', a)
【例6-10】编写程序,找出矩阵中的马鞍点。所谓马鞍点,即对于矩阵am×n中的某个元素a[i][j]是第i行的最大值,同时又是第j列中的最小值,则称此元素为该矩阵中的一个马鞍点。(要求:读懂代码)
'''
算法分析:
1)、依次找出第1、2、3行的最大值,
2)、然后找出各行最大值所在的列,判断该值在这列中是否是最小值
'''
a = [[2, 3, 3],
[4, 5, 6],
[7, 5, 4]] # 3*3的矩阵
n = len(a)
num = 0 # num用于统计马鞍点个数
for i in range(n):
row_max = max(a[i]) # 求出第i行的最大值
for j in range(n):
if a[i][j] == row_max: # 找到最大值所在列号j,接下来找j列的最小值
col_min = a[i][j] # 初始化j列最小值,a[i][j]代表i行的最大值,
for k in range(n): # 求出该列的最小值
if a[k][j] < col_min:
col_min = a[k][j]
if col_min == row_max: # 判断行最大值和列最小值相等,则马鞍点出现
num += 1
print('马鞍点:', (i, j))
if num == 0:
print('没有马鞍点!')
编写程序,打印10行的杨辉三角。
'''
杨辉三角可以看着是第1列和主对角线全为1,其他元素是头顶元素和头顶前一个元素之和的二维数组
方法一:
'''
l=[[1 if j==0 or j==i else 0 for j in range(10)] for i in range(10)]
for i in range(1,10):
for j in range(1,10):
l[i][j] = l[i-1][j-1]+l[i-1][j]
'''
方法二:
'''
l1 = [1]
l2 = [ ]
n = 0
while n<10:
l2.append(l1)
l1 = [sum(t) for t in zip([0]+l1, l1+[0])]
n += 1
约瑟夫问题。给10个学生编号1-10,按顺序围城一圈,按1-3报数,凡报到3者出列,然后下一个人继续从1开始报数,直到最后只剩下一个人,计算剩下这个人是第几号学生并输出。
算法分析:定义一个10个学生编号的列表,元素的值全为1,元素的下标0-9对应学生编号1-10。
报数的过程就是将列表中对应的元素值相加的过程,当加到3时,说明该同学出列,
并将该元素值设为0,同时学生总数减1,直到最后学生总数为1时终止。
num = int(input("请输入学生总数:"))
listNo = [ ]
for i in range(num):
listNo.append(1)
# 将列表元素初始化为1
j = 0
# 构成一个圈依次计数
sum1 = 0
# 累计到3数数
while True:
sum1 += listNo[j]
if sum1 == 3 :
listNo[j] = 0
# 表示下标为j的同学出列
sum1 = 0
# 为下次计数做准备
print(listNo)
# 测试,观察出列情况
num -= 1
# 学生总数减1
if num == 1 :
# 只有一位同学时,循环结束
break
j += 1
if j >= len(listNo):
# 到达列表最后一个元素时,应从头开始
j = 0
for i in range(len(listNo)):
if listNo[i] == 1:
print("最后剩下的同学编号是{}".format(i+1))
break
请输入学生总数:10
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
[1, 1, 0, 1, 1, 1, 1, 1, 1, 1]
[1, 1, 0, 1, 1, 0, 1, 1, 1, 1]
[1, 1, 0, 1, 1, 0, 1, 1, 0, 1]
[1, 0, 0, 1, 1, 0, 1, 1, 0, 1]
[1, 0, 0, 1, 1, 0, 0, 1, 0, 1]
[0, 0, 0, 1, 1, 0, 0, 1, 0, 1]
[0, 0, 0, 1, 1, 0, 0, 0, 0, 1]
[0, 0, 0, 1, 0, 0, 0, 0, 0, 1]
[0, 0, 0, 1, 0, 0, 0, 0, 0, 0]
最后剩下的同学编号是4
列表数据类型实际应用
将彩色图片进行灰色处理
import matplotlib.pyplot as plt # plt 用于显示图片
import matplotlib.image as mpimg # mpimg 用于读取图片
import numpy as np
lena = mpimg.imread('car.jpg') # 图片和代码处于同一目录下的 car.jpg
# 此时 lena 就已经是一个 np.array 了,可以对它进行任意处理
lena.shape #(512, 512, 3)
#print(lena[0][0][1])
plt.imshow(lena) # 显示图片
plt.axis('on') # 显示坐标轴
plt.show()
#gray = np.dot(lena[...,:3], [0.299, 0.587, 0.114])
# 也可以用 plt.imshow(gray, cmap = plt.get_cmap('gray'))
r, g, b = lena[:,:,0], lena[:,:,1], lena[:,:,2]
gray = 0.2989 * r + 0.5870 * g + 0.1140 * b
plt.imshow(gray, cmap='Greys_r')
plt.axis('off')
plt.show()
完成课后练习编程题
什么叫序列?哪几种属于有序序列,哪几种属于无序序列?
用列表推导式生成包含10个数字5的列表。
编写程序,模拟列表的 index()方法。
编写程序,模拟列表的 count()方法
编写程序,模拟列表的 remove()方法。
编写程序,输入一个列表a,计算得到一个元组t,该元组t的第一个元素为列表a的最大5值,其余元素为该最大值在列表a中的下标
编写程序,打印10行的杨辉三角。
编写程序,打印九九乘法表。
编写程序,输入两个正整数,计算得到一个元组,该元组第一个元素为两个整数的最大公约数,第二个元素为最小公倍数。
编写程序,实现将矩阵顺时针旋转90度。
编写程序,随机生成一个包含20个元素的列表,将该列表的前10个元素按降序排序,后10个元素按升序排序。
编写程序,随机生成[0,100范围内的20个不重复的随机数,存入列表中,并将该列表奇数下标的元素升序排序,偶数位置不变。