Reputation: 183
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
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
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