编写一个程序,实现二维列表的转置
本来这应该是一个简单的问题,但是我在复盘的时候,发现了一些小问题,所以拿来说一下。
方法一
m=[[1,2,3],[4,5,6],[7,8,9]]
new_m=[[0,0,0],[0,0,0],[0,0,0]]
for i in range(len(m)):
for j in range(len(m[0])):
new_m[j][i]=m[i][j]
print(new_m)
这是我最开始敲的,直接通过遍历后替换的操作实现转置,这种方法采用了for循环嵌套的方法,遍历了子列表,然后直接用索引的交换实现转置。
另外一种利用列表表达式实现的。那既然说到了列表表达式,我们也来复习一下。
列表表达式
什么是列表表达式?简单讲就是形如`[i for i in range(1,10)]`的表达式,列表表达式是将一个列表(实际上适用于任何可迭代对象)转换成另一个列表的工具。
在转换过程中,可以指定元素必须符合一定的条件,才能添加至新的列表中,这样每个元素都可以按需要进行转换。
每个列表表达式都可以重写为 for 循环,但不是每个 for 循环都能重写为列表解析式,列表表达式比`for`循环嵌套更精简,运行更快。
以下是基本的语法
基本语法
[expression for iter_val in iterable]
[expression for iter_val in iterable if cond_expr]
举个简单的例子看一下
编写程序,将 1-10 每个数乘以 2 放入一个列表
·利用for循环
lst=[]
for i in range (1,11):
i*=2
lst.append(i)
print(lst)
·利用列表表达式
lst=[i*2 for i in range(1,11)]
print(lst)
很明显,列表表达式更加简洁。
复杂的列表推导式
[x*y for x in range(1,5) if x > 2 for y in range(1,4) if y < 3]
对于这种复杂的列表推导式 ,我们需理解他的运行顺序。
for x in range(1,5):
if x>2:
for y in range(1,4):
if y<3:
x*y
那我们回到题目 。
方法二
m=[[1,2,3],
[4,5,6],
[7,8,9],
[10,11,12]]
new_m=[[m[j][i] for j in range(len(m))] for i in range(len(m[0]))]
print(new_m)
我们先定义一个二维列表。
在使用中,我们通常设置行-i,列-j,转置就是将行变成列,列变成行。
行--i-->列 列--j-->行
[ -- for j in range(len(m)) ] for i in range(len(m[0]) ]
那对于推导式就是将子列表的变成j去遍历,外列表变成i去遍历
然后我们要让谁去参与推导呢?很显然是m。
那m的索引怎么表示呢?我们希望m的(2,1),变成new_m的(1,2)。
详细的解答过程可视化:
内层 [ m[j][i] for j in range(len(m)) ]
[ m[0][i] m[1][i] m[2][i] m[4][i] ]
外层 for i in range(len(m[0]))
[ m[0][0] m[1][0] m[2][0] m[4][0] ]
[ m[0][1] m[1][1] m[2][1] m[4][1] ]
[ m[0][2] m[1][2] m[2][2] m[4][2] ]