It is an error when initializing the list. In Python when it is done:
a = [1,2,3]
b = a
b
is not a true copy of a
, but it contains the same list literally, what has been done is to pass the object reference a
to b
. If we modify now b
, the changes also occur in a
:
b[0] = 8
print(a[0])
>>> 8
This is what is happening to you, when you initialize the list (matrix) and fill it with zeros you do this:
a=[[0]*nx]*ny
That for your example is:
a=[[0]*5]*2
or something more developed:
a=[[0,0,0,0,0]]*2
Here is the problem, it seems that we are creating two different lists within a
but what is really happening is that two lists have been created with the same reference as before, both Nested lists are the same in memory. When the second (y = 1) is modified in the cycle, the first one (which is actually the same) is also modified so that the output is:
[[5, 6, 7, 8, 9], [5, 6, 7, 8, 9]]
The solution is to initialize the list using a for:
a = []
for _ in range(ny):
a.append([0]*nx)
However, it is better and more efficient using List Comprehensions:
nx = 5
ny = 2
a=[[0]*nx for _ in range(ny)]
for x in range(0, ny):
for y in range(0, nx):
a[x][y]=x * nx + y
print(x * nx + y)
print("===========")
for x in range(0, ny):
for y in range(0, nx):
print(a[x][y])
We can check whether or not in both cases by printing the memory addresses of both sublist (rows of the matrix):
nx = 5
ny = 2
a=[[0]*nx]*ny
print('Lista a:')
print(hex(id(a[0])))
print(hex(id(a[1])))
print(a[0] is a[1])
b=[[0]*nx for _ in range(ny)]
print('\nLista b:')
print(hex(id(b[0])))
print(hex(id(b[1])))
print(b[0] is b[1])
This returns something like:
List to:
0x232daa5b508
0x232daa5b508
True
List b:
0x232dce65d48
0x232dce54648
False
We see how in the first case both sublists are the same object in memory but this does not happen in the second case.