第十三章 如何创建二维矩阵

  • 注意创建二维列表时候的[]所包括的内容
  • 二维列表不能像其他语言一样很快速的生成,效率要相对慢一点

示例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
  1. 达到效果,但是格式不理想
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()
  1. 达到预期效果
    这里可以根据示例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]
具体实现步骤:

  1. 建立一个新的尺寸和旧矩阵相同的矩阵。赋值给变量mat2
  2. 使用之前的变换公式来给mat2的每个元素赋新值
  3. 让两个矩阵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
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值