1

I've written a class called Matrix.

class Matrix:
# Initialize a matrix
def __init__(self, rows: int = 1, columns: int = 1, data: list = []):
    self.data = data
    self.rows = rows
    self.columns = columns

I'm trying to change the data in only one instance of Matrix, but it changes the data in both instances.

from matrix import Matrix

m1 = Matrix()
m2 = Matrix()

for i in range(5):
    m1.data.append(i)

print(m1.data)
print(m2.data)

# expected result:
# [0, 1, 2, 3, 4]
# []

# actual result:
# [0, 1, 2, 3, 4]
# [0, 1, 2, 3, 4]

Edit:

Changed the Matrix class to this and I'm getting the desired behaviour:

class Matrix:
    # Initialize a matrix
    def __init__(self, rows: int = 1, columns: int = 1, data: list = []):
        if data:
            self.data = data
        else:
            self.data = []
        self.rows = rows
        self.columns = columns

2 Answers2

1

Default arguments are only evaluated once when declaring class, so both instances share same list (the one being default argument [] to init).

I think PyCharm even warns when you use mutable default arguments.

kwesolowski
  • 695
  • 8
  • 18
0

It is because 'data' is being initiated in the function definition as an optional argument, that means, it's scope is not limited to the function only.

And as you know, python treats everything as an object and uses variable to keep a reference to them. Initially, m1 is created and an empty list object is created in the memory which m1.data is pointing. And then, when m2 is created again with the default arguments, no new object is created. So, m2.data is pointing towards the same list.

Hence, if you add anything in m1.data list inplace, so it will reflect in m2.data. We doesn't see such thing with numbers because modifying a number will create a new object in the memory, i.e. if you add 2 to 1, then 3 is not replaced at the memory address of 1 else a new object is created with references accordingly.

Proper Solution

Initiate a list inside the function scope, i.e. inside the indentations.

Prashant Gupta
  • 439
  • 2
  • 10