在Python中/列表列表中获取所有对角线

问题描述 投票:44回答:8

我正在寻找一种Python方式来获取(正方形)矩阵的所有对角线,以列表列表的形式表示。

假设我有以下矩阵:

matrix = [[-2,  5,  3,  2],
          [ 9, -6,  5,  1],
          [ 3,  2,  7,  3],
          [-1,  8, -4,  8]]

然后大对角线很容易:

l = len(matrix[0])
print [matrix[i][i] for i in range(l)]              # [-2, -6, 7,  8]
print [matrix[l-1-i][i] for i in range(l-1,-1,-1)]  # [ 2,  5, 2, -1]

但是我很难想出一种生成所有对角线的方法。我正在寻找的输出是:

[[-2], [9, 5], [3,-6, 3], [-1, 2, 5, 2], [8, 7, 1], [-4, 3], [8],
 [2], [3,1], [5, 5, 3], [-2, -6, 7, 8], [9, 2, -4], [3, 8], [-1]]
python matrix diagonal
8个回答
49
投票

numpy中可能有比下面更好的方法,但是我对此不太熟悉:

import numpy as np

matrix = np.array(
         [[-2,  5,  3,  2],
          [ 9, -6,  5,  1],
          [ 3,  2,  7,  3],
          [-1,  8, -4,  8]])

diags = [matrix[::-1,:].diagonal(i) for i in range(-3,4)]
diags.extend(matrix.diagonal(i) for i in range(3,-4,-1))
print [n.tolist() for n in diags]

输出

[[-2], [9, 5], [3, -6, 3], [-1, 2, 5, 2], [8, 7, 1], [-4, 3], [8], [2], [3, 1], [5, 5, 3], [-2, -6, 7, 8], [9, 2, -4], [3, 8], [-1]]

Edit:已更新为可推广用于任何矩阵大小。

import numpy as np

# Alter dimensions as needed
x,y = 3,4

# create a default array of specified dimensions
a = np.arange(x*y).reshape(x,y)
print a
print

# a.diagonal returns the top-left-to-lower-right diagonal "i"
# according to this diagram:
#
#  0  1  2  3  4 ...
# -1  0  1  2  3
# -2 -1  0  1  2
# -3 -2 -1  0  1
#  :
#
# You wanted lower-left-to-upper-right and upper-left-to-lower-right diagonals.
#
# The syntax a[slice,slice] returns a new array with elements from the sliced ranges,
# where "slice" is Python's [start[:stop[:step]] format.

# "::-1" returns the rows in reverse. ":" returns the columns as is,
# effectively vertically mirroring the original array so the wanted diagonals are
# lower-right-to-uppper-left.
#
# Then a list comprehension is used to collect all the diagonals.  The range
# is -x+1 to y (exclusive of y), so for a matrix like the example above
# (x,y) = (4,5) = -3 to 4.
diags = [a[::-1,:].diagonal(i) for i in range(-a.shape[0]+1,a.shape[1])]

# Now back to the original array to get the upper-left-to-lower-right diagonals,
# starting from the right, so the range needed for shape (x,y) was y-1 to -x+1 descending.
diags.extend(a.diagonal(i) for i in range(a.shape[1]-1,-a.shape[0],-1))

# Another list comp to convert back to Python lists from numpy arrays,
# so it prints what you requested.
print [n.tolist() for n in diags]

输出

[[ 0  1  2  3]
 [ 4  5  6  7]
 [ 8  9 10 11]]

[[0], [4, 1], [8, 5, 2], [9, 6, 3], [10, 7], [11], [3], [2, 7], [1, 6, 11], [0, 5, 10], [4, 9], [8]]

18
投票

以对角线倾斜的方式开始。

如果(x,y)是矩阵内部的直角坐标,则要转换为坐标系(p,q),或从其中转换,其中p是对角线的数量,q是沿对角线的索引。 (所以p = 0是[-2]对角线,p = 1是[9,5]对角线,p = 2是[3,-6,3]对角线,依此类推。)

要将(p,q)转换为(x,y),可以使用:

x = q
y = p - q

尝试插入p和q的值以查看其工作原理。

现在,您只需循环...对于p从0到2N-1,q从max(0,p-N + 1)到min(p,N-1)。将p,q转换为x,y并打印。

然后为其他对角线,重复循环,但使用不同的变换:

x = N - 1 - q
y = p - q

((这实际上只是左右翻转矩阵。)

抱歉,我实际上没有在Python中编写代码。 :-)


10
投票

这是给Moe的,谁问了Moe


7
投票

我遇到了另一个有趣的解决方案。通过查看x和y的组合,可以立即发现行,列,向前和向后对角线。


4
投票

我最近终于重新发明了这个轮子。这是一种易于使用/扩展的方法,用于在方形列表列表中查找对角线:


1
投票

这仅适用于宽度和高度相等的矩阵。


0
投票

Pythonic方法


-1
投票

基于上述Nemo答案的代码:

© www.soinside.com 2019 - 2024. All rights reserved.