Home>
import functools
import matplotlib.pyplot as plt
from math import *
import random
class Matrix:
    def __init__(self,rows=0,cols=0,matr=[]):
        self.rows= rows
        self.cols= cols
        self.matr= matr
    def __add__(self,m):
        if (self.rows != m.rows or self.cols != m.cols):
            return "Wrong size"
        res= Matrix(self.rows,self.cols,[])
        for i in range(self.rows):
            res.matr.append(list(map(lambda x,y:x+y,self.matr[i],m.matr[i])))
        return res
    def __mul__(self,m):
        if isinstance(m,int):
            result= Matrix(self.rows,self.cols,[])
            for i in range(self.row):
                result.matr.append(list(map(lambda x: m*x, self.matr[i]))   )
        elif isinstance(m,Matrix):
            if (self.cols != m.rows):
                return "Wrong size"
            res= Matrix(self.rows,m.cols,[])
            for i in range(self.rows):
                tmp=[]
                for j in range(m.cols):
                    c=0
                    for k in range(self.cols):
                        c+=(self.matr[i][k]*m.matr[k][j])
                    tmp.append(c)
                res.matr.append(tmp)
            return res

The crux of the matter is this: when adding/multiplying methods work, if you do not explicitly specify when creating res (within these methods) that res.matr= [] (this is explicitly specified when calling the constructor), then when performing several addition operations /multiplication the next time one of the operators is used, res.matr will not be empty at all, it will contain the result of the previous call. If specified explicitly in the constructor, then the problem is solved (as it is done in the code below). Question: why so? After all, by default it is indicated that matr= [].

Can you add an example call sequence?

Dmitry2022-01-30 23:11:43
  • Answer # 1

    Questions like this have been answered here many times. The fact is that in python, default parameters work differently than in other languages. Function and method definitions are processed once -when the interpreter reads the function/method definition. That's when the default settings are set. When calling functions/methods, they are no longer exposed. Therefore, in python, it is not recommended to use collections as default parameters -they are not reset to the initial state, but are reused, which is what you observe. Makes it workNoneas the default parameter and then checking for that value. For example, like this in your case:

    class Matrix:
        def __init__(self,rows=0,cols=0,matr=None):
            self.rows= rows
            self.cols= cols
            if matr is None:
                self.matr= []
            else:
                self.matr= matr
    

    You can do thisifin one line using the ternary operator:

    self.matr= [] if matr is None else matr
    

    Or very briefly, using the knowledge of the boolean values ​​of empty objects andNoneand non-empty objects:

    self.matr= matr or []
    

    Thank you very much, now I understand what the problem is ^_^

    R Georgy2022-01-31 10:03:36