Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

listing elements in a nested lists diagonally [duplicate]

this is my first post, i'm pretty new this awesome site.

i'd like to list all elements in a 3x3 array diagonally:

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

expected output:

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

Also, how would I generalize it to any N x N array?

Edit: I've noticed this has been asked before yet i'm looking for a way without importing numpy or any library for that matter.

Edit2: One of my classmates offered this solution, I like it the most:

Since you finding diagonals starting from the bottom left corner, you could do this by starting in the top right corner of the square and reversing your solution in the end. My approach was first reversing each row in L, and then appending each element to its corresponding diagonal list. The insight here is that you start appending elements in each row K not in the first sub-list of the final list, but starting at indice K. For instance after reversing row [4,5,6] to row [6,5,4], I would append 6 to the 2nd sublist of my diagonally ordered list (since this is the 2nd row), then I would append 5 to the 3rd sublist, and then I would append 4 to the fourth sublist. However, if I didn't have a fourth sublist at the moment in time in my diagonal list, I would add a fourth empty list, then fill it with 4.

My explanation may not be too clear, so here's the code I have.

def diagonal(l):

    L = l[:]
    return_list = [[] for i in range(len(L))]

    for line in range(len(L)):
        L[line].reverse()
        i = line

        for elem in L[line]:
            if i >= len(return_list):
                return_list.append([])

            return_list[i].append(elem)
            i += 1

    return_list.reverse()
    return return_list
like image 838
Moe Avatar asked Apr 14 '14 20:04

Moe


People also ask

How do you extract the diagonal elements of a matrix in python?

NumPy diag() function in Python is used to extract a diagonal or construct a diagonal array. This function takes an array and k as parameters and returns the diagonal array from the given array.

How do you find the diagonal elements of a matrix?

D = diag( v ) returns a square diagonal matrix with the elements of vector v on the main diagonal. D = diag( v , k ) places the elements of vector v on the k th diagonal. k=0 represents the main diagonal, k>0 is above the main diagonal, and k<0 is below the main diagonal.


1 Answers

Using only Python (no NumPy):

import itertools as IT

L = [  [1, 2, 3],
       [4, 5, 6],
       [7, 8, 9] ]
N = len(L)
d = dict()
for i,j in IT.product(range(N), repeat=2):
    d.setdefault(j-i, []).append((i,j))

print([[L[i][j] for i,j in d[k]] for k in range(-N+1, N)])    
# [[7], [4, 8], [1, 5, 9], [2, 6], [3]]

Or, even better, use Nemo's transformation (generalized to h x w shaped matrices:

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

h, w = len(L), len(L[0])

print([[L[h-1-q][p-q]
        for q in range(min(p, h-1), max(0, p-w+1)-1, -1)]
       for p in range(h+w-1)])                             
# [[7], [4, 8], [1, 5, 9], [2, 6], [3]]

We can also put this code in a function for easier usage:

def diagonals(L):
    """
    https://stackoverflow.com/a/31373955/190597 (unutbu)
    >>> L = array([[ 0,  1,  2],
                   [ 3,  4,  5],
                   [ 6,  7,  8],
                   [ 9, 10, 11]])

    >>> diagonals(L)
    [[9], [6, 10], [3, 7, 11], [0, 4, 8], [1, 5], [2]]
    """
    h, w = len(L), len(L[0])
    return [[L[h - p + q - 1][q]
             for q in range(max(p-h+1, 0), min(p+1, w))]
            for p in range(h + w - 1)]


def antidiagonals(L):
    """
    >>> L = array([[ 0,  1,  2],
                   [ 3,  4,  5],
                   [ 6,  7,  8],
                   [ 9, 10, 11]])

    >>> antidiagonals(L)
    [[0], [3, 1], [6, 4, 2], [9, 7, 5], [10, 8], [11]]
    """
    h, w = len(L), len(L[0])
    return [[L[p - q][q]
             for q in range(max(p-h+1,0), min(p+1, w))]
            for p in range(h + w - 1)]
like image 185
unutbu Avatar answered Sep 17 '22 06:09

unutbu