转换这个矩阵(python3)
我正在寻找一种方法来转置一个矩阵,比如说:
[[1, 2, 3],
[4, 5, 6],
[7, 8, 9]]
这样就会把矩阵变成:
[[1, 4, 7],
[2, 5, 8],
[3, 6, 9]]
到目前为止,我尝试了几种方法,但都没有成功。我试过:
def transpose_matrix(matrix): # this one doesn't change the matrix at all
zip(*matrix)
return matrix
或者
def transpose_matrix(matrix):
map(list, zip(*matrix))
return matrix
或者
def transpose_matrix(matrix): # this one returns an empty list []
print(list(zip(*matrix)))
我想自己编写代码,而不使用像 numpy
这样的外部库。
之后,它会把结果返回到这个菜单,并使用转置后的矩阵进行后续选项(未显示):
def menu(matrix):
print('choose option')
loop = True
while loop:
print('''
1-display matrix
7-transpose it
8-other option
0-back
''')
choi = input('cchoice:')
if choi =='1':
print('\n'.join([' '.join(map(str, row)) for row in matrix]))
elif choix == '7':
matrix = transpose_matrix(matrix)
else:
print('invalid choice')
2 个回答
1
你尝试的解决方案有一些问题:
def transpose_matrix(matrix):
zip(*matrix)
return matrix
你用 zip(…)
得到的结果被丢掉了,你返回的是原来的矩阵。应该写成 return zip(*matrix)
。
def transpose_matrix(matrix):
map(list, zip(*matrix))
return matrix
和上面一样,map(…)
得到的结果也被丢掉了。应该写成 return map(list, zip(*matrix))
。
def transpose_matrix(matrix):
print(list(zip(*m)))
参数叫 matrix
,但你在用 m
。所以要么把参数 m
改个名字,要么把压缩后的值改成 *matrix
。
示例:
>>> m = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
>>> list(zip(*m))
[(1, 4, 7), (2, 5, 8), (3, 6, 9)]
>>> list(map(list, zip(*m)))
[[1, 4, 7], [2, 5, 8], [3, 6, 9]]
2
你其实并没有真正“赋值”你所做的操作的结果,所以返回的还是原来的 matrix
,没有改变。例如:
def transpose_matrix(matrix):
zip(*matrix) # ignore result of computation
return matrix # return argument unchanged
相反,你可以试试:
def transpose_matrix(matrix):
matrix = list(map(list, zip(*matrix))) # assign result
return matrix # return transposed matrix
或者简单地:
def transpose_matrix(matrix):
return list(map(list, zip(*matrix)))
记住,你在调用这个函数的时候,也需要把返回的结果赋值给调用的函数:
matrix = transpose_matrix(matrix)
就地修改
另外,你可以选择就地转置,并隐式地 return None
:
def transpose_matrix(matrix):
matrix[:] = list(map(list, zip(*matrix)))
这样在调用函数的时候,你就不需要再把结果赋值回 matrix
了。
示例
下面是这些函数实际运行的例子:
>>> def transpose_matrix(matrix):
return list(map(list, zip(*matrix)))
>>> transpose_matrix([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
[[1, 4, 7], [2, 5, 8], [3, 6, 9]]
>>> def in_place_transpose(matrix):
matrix[:] = list(map(list, zip(*matrix)))
>>> m = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
>>> in_place_transpose(m)
>>> m
[[1, 4, 7], [2, 5, 8], [3, 6, 9]]
zip
的行为
需要注意的是,zip
会把输出截断到最短的参数可迭代对象,比如:
>>> a = [1, 2, 3]
>>> b = [4, 5, 6]
>>> c = [7, 8]
>>> d = [9]
>>> e = []
>>> for l in (b, c, d, e):
print(list(zip(a, l)))
[(1, 4), (2, 5), (3, 6)]
[(1, 7), (2, 8)]
[(1, 9)]
[]
所以如果你的 matrix
中有任何一行是空列表,输出就会是一个空列表。你可以使用 zip_longest
来自 itertools
来插入虚拟的 fillvalue
(默认是 None
):
>>> from itertools import zip_longest
>>> list(zip_longest([1, 2, 3], [4, 5]))
[(1, 4), (2, 5), (3, None)]
>>> m = [[1, 2, 3], [4, 5, 6], []]
>>> list(zip_longest(*m, fillvalue=0))
[(1, 4, 0), (2, 5, 0), (3, 6, 0)]
你可以这样实现:
def transpose_matrix(matrix):
return list(map(list, zip_longest(*matrix, fillvalue=0)))
在你的脚本顶部加上 from itertools import zip_longest
。