"the program always returns true"
It’s not true, I tested it with a non-symmetric matrix and it returned False
:
m = [ [3, 2, 5], [1, 5, 6], [15, 4, 7] ]
print(simetrica(m)) # False
Just a few details to settle/improve.
Actually what you have is not really a matrix, but a list of lists (the only native form of the language to simulate matrices).
This is because in an array of dimensions M x N (M rows and N columns), all M rows have exactly N elements. But in a list list, there is no such obligation (there is nothing in the language that requires to have a certain size, it is you who have to control and ensure this): each "line" can have a different amount of elements. So nothing prevents me from having a "matrix-that-isn’t-a-matrix":
m = [
[3],
[2, 5, 6],
[5, 6]
]
Thus, the function would also need to verify that all "lines" have the same amount of elements. For example, if we pass a list like:
m = [
[3, 2, 5],
[2, 5, 6, 8],
[5, 6, 7]
]
The function returns True
. That’s because the loop intern (for j
) only goes as far as len(mat[0])
, which is the size of the first "line", and since it only has 3 elements, the fourth element of the second "line" (number 8) is ignored by loop.
Also, as a symmetrical matrix can only be square (the number of rows is equal to the number of columns), we can use any
to check if each of the "lines" has the same size as the "matrix". Something like this:
if any(len(linha) != len(mat) for linha in mat):
return False
That is, if any "line" has a different size, I return False
and no need to continue.
Another improvement is that you don’t need to go through all the elements. Checking the diagonal is redundant (because diagonally, i
is equal to j
, then in fact you will be comparing the element with itself). Just go to the diagonal and compare one of the "halves" with the other "half". For example, if I compared the element mat[0][1]
with mat[1][0]
, is redundant to make another comparison of mat[1][0]
with mat[0][1]
. That is, the j
doesn’t have to go from start to finish, it can only go up i
:
def simetrica(mat):
if any(len(linha) != len(mat) for linha in mat):
return False
for i in range(len(mat)):
for j in range(i): # só vou até a diagonal
if mat[i][j] != mat[j][i]:
return False
return True
One detail is that so we have to go through the matrix twice: one to check the sizes (the if any(...)
), and another to compare the elements. But if you want, you can do everything at once:
def simetrica(mat):
for i, linha in enumerate(mat):
if len(linha) != len(mat): # tamanho diferente, não é matriz quadrada
return False # então não pode ser simétrica
for j in range(i):
if linha[j] != mat[j][i]:
return False
return True
It seems to be correct. I could do an optimization, to go through only half of the matrix, because make the comparison
i, j = A, B
will be the same comparison ofi, j = B, A
, beingA
andB
positions in the matrix, so there is no need to do both; one of them is already sufficient to ensure symmetry.– Woss