AndyM3
AndyM3

Reputation: 183

How to add the diagonals of a matrix in Python 3.3.5

I am using numpy. My assignment is:

"Write a function sumOfDiagonal that has one parameter of type list. The list is a 4x4 2-dimensional array of integers (4 rows and 4 columns of integers). The function returns the sum of the integers in the diagonal positions from top left to bottom right. The function should return 14 for the list below. You can assume the list is always a 4x4 2-dimensional integer array. 4 9 2 5

3 1 10 6

7 2 5 1

8 8 1 4"

I am struggling very much with this one. I've tried a few approaches and got nothing. At first I tried:

def sumOfDiagonal (list1: list):

 summation1=[i.split(", ")[0] for i in list1]

return (summation1)

print (sumOfDiagonal ([[4, 9, 2, 5], [3, 1, 10, 6], [7, 2, 5, 1], [8, 8, 1, 4,]]))

because I saw on another thread that supposedly this could be done, and I thought I could split the input array up by the individual lists for a helpful first start, but I got an error about not having an attribute...I just tried it again and I got an error about calling an outside function

I then made several other attempts in another direction. What I have right now is:

def sumOfDiagonal (list1: list):

i=0
j=0
summation1=0
for row in list1:
    for i in row:

        for column in list1:
            for j in column:

                summation1=list1[i j],row[i]+summation1

return (summation1)

print (sumOfDiagonal ([[4, 9, 2, 5], [3, 1, 10, 6], [7, 2, 5, 1], [8, 8, 1, 4,]]))

This clearly isn't working but I had some version of this without syntax errors before and only with a logic error (it was outputting 44)

I think that was something like

def sumOfDiagonal (list1: list):

i=0
j=0
summation1=0
summation2=0
for row in list1:
    summation1=row[1]+summation1
    i+=i

for column in list1:
    summation2=column[i]+summation2
    i+=i

return (summation1+summation2)

print (sumOfDiagonal ([[4, 9, 2, 5], [3, 1, 10, 6], [7, 2, 5, 1], [8, 8, 1, 4,]]))

am I even close to being right, and how can I correct the massive pile of fail that I have?

Many thanks in advance

Upvotes: 3

Views: 4444

Answers (2)

hpaulj
hpaulj

Reputation: 231365

There are many of ways to do this:

Starting with a multiline string, parsing, selecting the diagonal, and summing can be done in one line:

txt = """4 9 2 5
3 1 10 6
7 2 5 1
8 8 1 4"""
sum([int(x.split()[i]) for i,x in enumerate(txt.splitlines())])

Or splitting up the steps:

getting a list of lists by splitting lines

LOL = [[int(y) for y in x.split()] for x in txt.splitlines()]
# [[4, 9, 2, 5], [3, 1, 10, 6], [7, 2, 5, 1], [8, 8, 1, 4]]

and sum the diagonal

sum(v[i] for i,v in enumerate(lol))
# 14

If this is indeed a numpy assignment, genfromtxt is a handy tool for getting an array from txt

X=np.genfromtxt(txt.splitlines())
#
array([[  4.,   9.,   2.,   5.],
       [  3.,   1.,  10.,   6.],
       [  7.,   2.,   5.,   1.],
       [  8.,   8.,   1.,   4.]])

The array has its own function to get the diagonal and sum

X.diagonal().sum()
# 14.0
X.trace()
np.einsum('ii',X)

Other iterations:

s = 0
for i in range(4): 
    s += X[i,i]
    # s += lol[i][i]

Or if you want to iterate on both dimensions of the array:

s = 0
for i in range(4):
    for j in range(4):
        if i==j:   
            s += lol[i][j]

Upvotes: 1

davidlowryduda
davidlowryduda

Reputation: 2559

When I find the trace of a matrix by hand, I first look at the top left, then add it to the second element in the second row, and then the third element in the third row, and so on. This will guide us here. This can be a good source of programming logic inspiration - if you can do it by hand algorithmically, you can program it.

In short, I think you are overthinking it. Here are two options, assuming a list of lists, as in your example.

def sumOfDiagonal(matrix):
    sum = 0
    for i in range(len(matrix)):
        sum += matrix[i][i]        #These are the diagonal elements
    return sum

Or alternatively, if you want to do it all at once and find range(len(x)) to be unpythonic,

def sumOfDiagonal2(matrix):
    return sum([matrix[i][i] for i,_ in enumerate(matrix)])

Upvotes: 1

Related Questions