【发布时间】:2015-10-17 09:22:27
【问题描述】:
考虑以下 3 x 4 矩阵,它在 Python 中实现为 3 个长度为 4 的列表:
>>> matrix = [[1, 2, 3, 4],[5, 6, 7, 8],[9, 10, 11, 12]]
以下列表推导将重新排列矩阵转置的行和列:
>>> [[row[i] for row in matrix] for i in range(4)]
[[1, 5, 9], [2, 6, 10], [3, 7, 11], [4, 8, 12]]
但假设我需要这个结果:
[[1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12]]
这是一个重新排列的 4 x 3 矩阵,以便获得原始矩阵的连续“滚动”,每 3 个元素“中断”到新行。
我知道可以制定出一种算法来完成这项任务,但是是否有可能仅使用列表推导式来获得它?(如果是,如何?)
编辑:
接受的答案应满足以下要求:
- 必须在基本/干净的 Python 安装上工作(没有额外的库);
- 必须是(类似于矩阵转置)“单线”。
第二次编辑 + 接受的答案动机:
当我不得不为此寻找解决方案时,我做了以下事情(基于我在下面我自己的 cmets 中给出的建议):
mat = [[1,2,3,4],[5,6,7,8],[9,10,11,12]]
[[mat[(3*(i-1)+j -1)//4+1][(3*(i-1)+j -1)%4] for j in range(3)] for i in range(4)]
请注意,我写的解决方案是针对这种情况的,但正如 Clodion 也注意到的那样,“公式”可以“概括”,以便将初始(列表列表)矩阵重新排列为不同的“形状"。
【问题讨论】:
-
@Clodion(征求建议)和谁可能需要或感兴趣,我知道的是:命名
ir , ic初始矩阵行和列的总数 ,i , j初始矩阵行和列的索引和r , c重新排列的索引,具有k = ic*(i-1)+j,“索引重新映射公式" 将是r = (k-1) // ir + 1和c = (k-1) % ir + 1。附言请注意,c也可以通过这种方式重新映射:c = (j % ic if j % ic > 0 else i)。 -
所以,在这种情况下:
ir=3、ic=4、k = 4*(i-1)+j、r = (k-1) // 3 + 1和c = (k-1) % 3 + 1(甚至是c = (j % 4 if j % 4 > 0 else i))。 -
P.S.获取原始矩阵的行数和冒号可以分别使用:
len(mat)和len(mat[0]) -
P.P.S.显然,我在上一条评论中真正的意思是 columns,not colons。
标签: python list matrix list-comprehension