0

Given an mxn matrix, and an element's indices, how can I use pure python (no numpy or any matrix packages) to obtain both diagonals that contain that element?

For example:

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

Given element (1, 2), I could get the main diagonal: [2, 7, 12], and [4, 7, 10, 0]. I've seen this post, but I don't care to wrap around the matrix. Also, that solution is very difficult for me to understand, so I'm having trouble re-writing it to fit my needs.

TheRealFakeNews
  • 7,512
  • 16
  • 73
  • 114
  • What exactly is a "matrix" supposed to be in pure Python? – Stefan Pochmann Oct 21 '17 at 21:36
  • a multidimensinoal array – TheRealFakeNews Oct 21 '17 at 21:36
  • Given an arbitrary element's location, `mat[i][j]`, the diagonals it is in are realated to `i` & `j` in a fixed way: i.e. `mat[i, j-1]` and `mat[i, j+1]` are two candidate locations (assuming the computed indices are valid). For the other diagonal, examples would be `mat[i-1, j]` and `mat[i+1, j]`. You simply have to gather them together in both directions. Python has no built-in matrix `get_diagonal()` functions. If you don't want wrapping, then don't do it. – martineau Oct 21 '17 at 21:48
  • @martineau Those four neighbor locations don't look like diagonals to me... – Stefan Pochmann Oct 21 '17 at 22:30
  • @Stefan: Your right, I got the math for the diagonal neighbors wrong, but the basic idea that they all follow the same pattern—which was the main point—and still holds true. – martineau Oct 21 '17 at 23:27
  • Correction: The diagonals for `mat[i][j]` would run `mat[i-1][j-1]` and `mat[i+1][j+1]` for lower-to-upper diagonals, and `mat[i-1][j+1]` and `mat[i+1][j-1]` for the other direction. – martineau Oct 21 '17 at 23:37
  • @martineau Is it possible to do this in one line in python? – TheRealFakeNews Oct 22 '17 at 13:22
  • @AlanH: No, I don't think you can do it with one line of code. Why? Regardless, I reopened your question since it's not quite an _exact duplicate_ of [**Get diagonal without using numpy?**](https://stackoverflow.com/questions/20447210/get-diagonal-without-using-numpy). I think you need to [edit] your question and clarify what the results should be if there's no wrapping (especially for the corner cases). – martineau Oct 22 '17 at 18:15

1 Answers1

0

Here's something that does what you want in Pure Python™:

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

def get_diags(mat, i0, j0):
    """ Return both diagonals that contain element mat[i0][j0]. """
    height, width = len(mat), len(mat[0])
    summ, diff = i0+j0, i0-j0
    diag1, diag2 = [], []
    for i in range(height):
        for j in range(width):
            if i-j == diff:
                diag1.append(mat[i][j])
            if i+j == summ:
                diag2.append(mat[i][j])

    return diag1, diag2

print(get_diags(mat, 1, 2))  # -> ([2, 7, 12], [4, 7, 10, 0])
martineau
  • 119,623
  • 25
  • 170
  • 301