The problem is that Python doesn’t have native types of "matrix" - in general, in small programs, people invent a kind of matrix - and programs that will do stuff muting with matrices, can use the Numpy library, which yes, has a type of matrix that has dozens of specific operations possible, is quite optimized, and etc...
And, especially for those who are starting in programming, or in Python, a very common way of representing an array is like a "list list", in which each internal list represents a matrix line. From your code, we can see that this was your approach.
So your problem is that when we have a compound object in Python, if we create another reference to it, the two references are to the same object. You avoid this with your matrix itself - the list list, when writing the line matriz_resultado=M[:]
- This is a Python expression that creates a "slice from the beginning to the end of a sequence", and therefore copies a list. Changes in this copy are not reflected in the original matrix.
However, you do not make copies of each row of your matrix: that is, the object list
which is line 0 of its matrix matriz_resultado
is the even object list
which is line 0 of its matrix M
.
So if you call your function with an "M1" test matrix, the result will be correct, but each row of the original matrix "M1" will be changed also, when the lines of matriz_resultado
are changed within the function. (And the line that was removed from the matriz_resultado
in full is not affected, of course).
A simple "print" between the calls to your function can make it very clear. In interactive mode I pasted exactly your code above, and called your function:
In [6]: a = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
In [7]: a
Out[7]: [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
In [8]: menor_complementar(a, 0, 0)
Out[8]: [[5, 6], [8, 9]]
In [9]: a
Out[9]: [[1, 2, 3], [5, 6], [8, 9]]
How to solve:
This is solved by ensuring that all sub-elements of your composite object, in this case, the matrix lines, are also copied when making a copy of the matrix that will be modified.
This could be done manually with a for
:
def menor_complementar(M, L, C):
matriz_resultato = [linha[:] for linha in M]
(in case the for
that copies each line is used in a "list comprehension").
But this use of for
can be complicated in more complex compound objects (if the elements of their matrices were themselves lists, instead of numbers, for example, or if their matrix was a given together with others in a dictionary, etc...).
The generic solution to this is the function deepcopy
in the module copy
from Python: it recursively copies each element of a compound object, whether its sub-elements are lists, dictionaries, sets and even instances of custom classes.
The following code is correct, using deepcopy
:
from copy import deepcopy
def menor_complementar(M,L,C):
#Onde: M é a matriz principal, L é o número da linha do elemento associado e C o número da coluna do elemento associado
matriz_resultado = deepcopy(M)
del(matriz_resultado[L])
for linha in matriz_resultado:
del(linha[C])
return matriz_resultado
Genial jsbueno! Solved my problem. Mto thanks for the force!!!
– VINI CIUS