0

Say I have a 2D array of 4 rows and 5 cols. I want to assign only the first row elements with their respective indices to get the below 2D array.

0 1 2 3 4
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0 

I first tried this:

array1 = [[0]*cols]*rows
print(array1)

for i in range(cols):
    array1[0][i] = i
print(array1)

Result:

[[0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0]]
[[0, 1, 2, 3, 4], [0, 1, 2, 3, 4], [0, 1, 2, 3, 4], [0, 1, 2, 3, 4]]

Which is not what I intended to do. Every row is being updated instead of just the first one.

But the following code gives the result I'm looking for.

array2 = [[0 for x in range(cols)] for y in range(rows)]
print(array2)
for i in range(cols):
    array2[0][i] = i
print(array2)

Result :

[[0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0]] 
[[0, 1, 2, 3, 4], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0]]

The only difference between both the snippets is the way array1 and array2 have been initialized. I'm curious to know why both of them work differently. Would appreciate any help.

-Thank You

PN07815
  • 123
  • 3
  • 8

1 Answers1

1

When you do array1 = [[0]*cols]*rows, all inner lists have the same reference, hence when you change one of the inner lists, all of them gets updated (All sublists updating to [0, 1, 2, 3, 4])

This behaviour can be seen in a simpler example below

In [9]: a =[[0]*2]*2                                                                                                                                                                                    

In [10]: a                                                                                                                                                                                              
Out[10]: [[0, 0], [0, 0]]

In [11]: a[0][0] = 1                                                                                                                                                                                    
#The first element of both sublists changed to 1
In [12]: a                                                                                                                                                                                              
Out[12]: [[1, 0], [1, 0]]

That is not the case when you initialize like array2 = [[0 for x in range(cols)] for y in range(rows)], where all inner lists have a different reference, hence you get the expected behaviour.

In [13]: a =[[0 for _ in range(2)] for _ in range(2)]                                                                                                                                                   

In [14]: a                                                                                                                                                                                              
Out[14]: [[0, 0], [0, 0]]
#The first element of only the first sublist changed to 1
In [15]: a[0][0] = 1                                                                                                                                                                                    

In [16]: a                                                                                                                                                                                              
Out[16]: [[1, 0], [0, 0]]

Hence the correct way to instantiate a 2D list is the second approach!

Devesh Kumar Singh
  • 20,259
  • 5
  • 21
  • 40