You could make a function that extracts the first row and last columns (outer edge) to form the first elements in the diagonals, then repeat the process iteratively on the remaining sub-matrix padding with leading&trailing zeroes and adding elements to the diagonals at each iteration:
def diagsDownLeft(M):
diags,pad = [],[]
while any(M):
edge = [*M[0][:-1] ,*next(zip(*map(reversed,M)))]
M = [r[:-1] for r in M[1:]]
diags.append(pad+edge+pad)
pad.append(0)
return [*map(list,zip(*diags))]
Output (for any rectangular matrix):
A = [[1, 2, 3],
[4, 5, 6],
[7, 8, 9]]
print(diagsDownLeft(A))
[[1, 0, 0], [2, 4, 0], [3, 5, 7], [6, 8, 0], [9, 0, 0]]
B = [[1, 2, 3, 10],
[4, 5, 6, 11],
[7, 8, 9, 12]]
print(diagsDownLeft(B))
[[1, 0, 0], [2, 4, 0], [3, 5, 7], [10, 6, 8], [11, 9, 0], [12, 0, 0]]
C = [[1, 2, 3],
[4, 5, 6],
[7, 8, 9],
[10, 11, 12]]
print(diagsDownLeft(C))
[[1, 0, 0], [2, 4, 0], [3, 5, 7], [6, 8, 10], [9, 11, 0], [12, 0, 0]]
How it works (visually):
1 2 3 1 2 3
4 5 6 x x 6
7 8 9 x x 9 ==> 1 2 3 6 9 (pad = none)
| | | | |
4 5 4 5 | | | | |
7 8 x 8 ==> 0 4 5 8 0 (pad = 0)
| | | | |
7 7 ==> 0 0 7 0 0 (pad = 0,0)
| | | | |
\ \ \ \ \__ [9,0,0] zipped
\ \ \ \___ [6,8,0]
\ \ \____ [3,5,7]
\ \_____ [2,4,0]
\______ [1,0,0]
If you also need the other diagonals:
def diagsDownRight(M):
diags,pad = [],[]
while any(M):
edge = [*next(zip(*reversed(M))), *M[0][1:]]
M = [r[1:] for r in M[1:]]
diags.append(pad+edge+pad)
pad.append(0)
return [*map(list,zip(*diags))]
Output:
print(diagsDownRight(A))
[[7, 0, 0], [4, 8, 0], [1, 5, 9], [2, 6, 0], [3, 0, 0]]
print(diagsDownRight(B))
[[7, 0, 0], [4, 8, 0], [1, 5, 9], [2, 6, 12], [3, 11, 0], [10, 0, 0]]
print(diagsDownRight(C))
[[10, 0, 0], [7, 11, 0], [4, 8, 12], [1, 5, 9], [2, 6, 0], [3, 0, 0]]
And opposite directions:
def diagsUpRight(M):
diags,pad = [],[]
while any(M):
edge = [*next(zip(*M)), *M[-1][1:]]
M = [r[1:] for r in M[:-1]]
diags.append(pad+edge+pad)
pad.append(0)
return [*map(list,zip(*diags))]
def diagsUpLeft(M):
diags,pad = [],[]
while any(M):
edge = [*M[-1][:-1],*next(zip(*map(reversed,M[::-1])))]
M = [r[:-1] for r in M[:-1]]
diags.append(pad+edge+pad)
pad.append(0)
return [*map(list,zip(*diags))]