文章目录
- 注意创建二维列表时候的[]所包括的内容
- 二维列表不能像其他语言一样很快速的生成,效率要相对慢一点
示例1 创建了一个8*9的乘法表:
def main():
rows=9
cols=8
mat=[[(m+1)*(n+1) for m in range(cols) ]for n in range(rows)]
my_format={:>3}
my_str=''
for i in range(rows):
my_str+=' '.join(i)
mystr+='\n'
print(mystr)
main()
- 其中的
mat=[[(m+1)*(n+1) for m in range(cols) ]for n in range(rows)]
语句就是创建二维列表的过程。 - 也可以先创建一个空间符合要求的二维列表,然后再进行赋值。如:
mat= [[0]*cols for i in range(rows)]
进行二维列表的创建。 - mat=[[0]*9]*8]这样是错的。
练习
1. 创建一个长字符串,并在程序末尾打印它,而不是大量调用print
- 达到效果,但是格式不理想
def main():
rows=9
cols=8
mat=[[(m+1)*(n+1) for m in range(cols) ]for n in range(rows)]
my_format='{:>3}'
my_list=[]
my_str=''
for i in range(rows):
for j in range(cols):
mylist.append(my_format.format(mat[i][j]))
mylist.append('\n')
print(''.join(my_list))
main()
- 达到预期效果
这里可以根据示例2的print_mat()程序改进
def main():
rows=9
cols=8
mat=[[(m+1)*(n+1) for m in range(cols) ]for n in range(rows)]
my_format='{:>3}'
my_list=['']
for i in range(rows):
for j in range(cols):
my_list.append(my_format.format(mat[i][j]))
my_list.append('\n')
print(''.join(my_list))
main()
1 2 3 4 5 6 7 8
2 4 6 8 10 12 14 16
3 6 9 12 15 18 21 24
4 8 12 16 20 24 28 32
5 10 15 20 25 30 35 40
6 12 18 24 30 36 42 48
7 14 21 28 35 42 49 56
8 16 24 32 40 48 56 64
9 18 27 36 45 54 63 72
2. 创建一个每维的长度都为2的四维矩阵,将每个元素都设置为: i * j * k * m ,这些值都为元素在各维的索引上加1(模拟索引从1开始的情形)
def main():
forth_list=[[[[
(i+1) * (j+1) * (k+1)*(m+1)
for i in range(0,2)]
for j in range(0,2)]
for k in range(0,2)]
for m in range(0,2)]
for m in range(2):
for k in range(2):
for j in range(2):
for i in range(2):
print(forth_list[m][k][j][i],end=' ')
print()
print()
print()
print()
main()
输出如下所示:
1 2
2 4
2 4
4 8
2 4
4 8
4 8
8 16
示例2 让用户初始化矩阵
让用户来为矩阵输入值
def main():
rows=cols=5
mat=[[0] * cols for i in range (rows)]
for i in range(rows):
s=input("enter a row of values")#输入一行的信息(数字)
s_list=s.split()
for j ,item in enumerate(s_list):
if j>=cols:
break
mat[i][j]=int(item)#这里不能直接复制item,因为item是string类型的。
print_mat(mat)
def print_mat(mat):
s = ''
for a_row in mat:
for item in a_row:
s+='{:>3}'.format(item)
s+='\n'
print(s)
main()
###优化代码:
for j ,item in enumerate(s_list):
if j>=rows:
break
这部分可优化:可以只读取0–(cols-1)的值就行,用切片代替上述的代码
for j , item in enumerate(s_list[:cols])
练习1 在这个程序的开头,让用户指定行数和列数:
修改第二行代码:
rows=int(input("请输入行数"))
cols=int(input("请输入列数"))
###练习2 修改程序,使将负值转为正值。
使用取绝对值函数即可
mat[i][j]=abs(int(item))
def main():
rows=int(input("请输入行数"))
cols=int(input("请输入列数"))
mat=[[0] * cols for i in range (rows)]
for i in range(rows):
s=input("enter a row of values")#输入一行的信息(数字)
s_list=s.split()
for j ,item in enumerate(s_list):
if j>=rows:
break
mat[i][j]=abs(int(item))#这里不能直接复制item,因为item是string类型的。
print_mat(mat)
def print_mat(mat):
s = ''
for a_row in mat:
for item in a_row:
s+='{:>3}'.format(item)
s+='\n'
print(s)
main()
实例3 如何旋转矩阵
如果希望将矩阵按顺时针旋转90度,应该怎么做呢?
4*4的二维矩阵中的元素[0][3]进行旋转: [i][j]
[0][3]
[3][4]
[4][0]
[1][0]
[0][3]
- i的值是j的旧值
- j的新值是4-i的旧值
所以如果进行旋转,则只需对每个单元格做如下变换:new_matrix[i][j]=old_matrix[4-j][i]
具体实现步骤:
- 建立一个新的尺寸和旧矩阵相同的矩阵。赋值给变量mat2
- 使用之前的变换公式来给mat2的每个元素赋新值
- 让两个矩阵mat1和mat2指向同一个矩阵。即mat1=mat2
- 这里被遗弃的原有的mat1实际是会被处理的,而不是一个真的没人管的“孤儿”,python的内存管理会做这样的事情,把它处理掉。
实现
具体实现如下:
n = 5
mat1 = [[0] * n for i in range(n)]
def main():
enter_mat_vals()
print_mat()
s=''
while not s or s[0] not in 'Nn':
rotate_mat()
print('Here is the rotated version:')
print_mat()
s=input('Rotated matrix again??(Y or N):')
def rotate_mat():
global mat1
mat2 = [[0] * n for i in range(n)]
for i in range(n):
for j in range(n):
mat2[j][n-1-i] = mat1[i][j]
mat1 = mat2
def enter_mat_vals():
for i in range(n):
s=input("Enter a row of values:")
a_list = s.split()
for j, item in enumerate(a_list[:n]):
mat1[i][j]=int(item)
def print_mat():
s=''
for i in range(n):
for j in range(n):
s+="{:>3}".format(mat1[i][j])
s+='\n'
print(s)
main()
- !一个缩进引发的血案,书上的一个缩进的bug,我找了好久才发现!,靠
代码改进
使用列表推导技术来简化代码。
def rotate_mat():
global mat1
mat2=[ [mat1[n-1-j][i] for j in range(n)]
for i in range(n)]
mat1=mat2
改进print_mat()
def print_mat():
s=''
for a_row in mat1:
for item in a_row:
s+="{:>3}".format(item)
s+='\n'
print(s)
- 用+=号之前需要提前定义左边的变量,因为这不是一个单纯的赋值操作。
使不在每次旋转都创建一个新矩阵,而是在两个矩阵之间相互切换。
mat1为当前矩阵时,mat2就是要修改的矩阵。
第一版
- 问题1:没有考虑开始时的状态,如果mat2和mat3都是默认的矩阵时。
- 问题2:这里可以使用python自带的语法来处理它。更具有python的风格。
#第一版
#需要添加全局变量mat2、mat3
mat2=[[0]*n for i in range(n)]
mat3=[[0]*n for i in range(n)]
def rotate_mat():
global mat1
global mat2
global mat3
if mat1==mat2:#问题1:没有考虑开始时的状态,如果mat2和mat3都是默认的矩阵时。
for i in range(n):
for j in range(n):
mat3[j][n-1-i] = mat2[i][j]#问题2:这里可以使用python自带的语法来处理它。更具有python的风格。
mat1 = mat3
elif mat1==mat3:
for i in range(n):
for j in range(n):
mat2[j][n-1-i] = mat3[i][j]
mat1 = mat2
下面的是改完之后的,自认为比较良好的函数。
第二版
def rotate_mat():
global mat1
global mat2
global mat3
if mat2==mat3:
print('True1')
for i,a_row in enumerate(mat1):
for j,item in enumerate(a_row):
mat2[i][j]=item
if mat1==mat2:
print('True2')
for i,a_row in enumerate(mat2):
for j,item in enumerate(a_row):
mat3[j][n-1-i]=item
mat1 = mat3
elif mat1==mat3:
print('True3')
for i,a_row in enumerate(mat3):
for j,item in enumerate(a_row):
mat2[j][n-1-i]=item
mat1 = mat2