0

I am trying to initialize an n by n list and then populate it by iterating through each row and column, but it doesn't work because say n = 2, [[None, None], [None, None]] does not get populated the same way as [[None] * 2] * 2.

For example:

n = 2 # int(input())
var_array = [[None] * n] * n
for i in range(n):
    for j in range(n):
        var_array[i][j] = (i, j)
        for v in var_array:
            print(v)
print(var_array)

Output: [[(1, 0), (1, 1)], [(1, 0), (1, 1)]] And that is because it populates both rows at col j instead of only row i:

>>> [[None, None], [None, None]] == [[None] * 2] * 2
True
>>> var1 = [[None, None], [None, None]]
>>> var2 = [[None] * 2] * 2
>>> var1[0][0] = 5
>>> var1
[[5, None], [None, None]]
>>> var2[0][0] = 5
>>> var2
[[5, None], [5, None]]

p.s. I am aware of better ways of populating an n by n list, but I need to do it this way - populate an already initialized 2d n by n list - to optimize a part of another program

  • You want `[[None]*n for _ in range(n)]` or `[[None for _ in range(n)] for _ in range(n)]` – juanpa.arrivillaga May 26 '22 at 23:30
  • @juanpa.arrivillaga right, I tried [[None] * n] * n instead because I thought it is faster especially for really large n, but apparently it doesn't work –  May 26 '22 at 23:36
  • It's faster *precisely because* of the behavior you are seeing, it doesn't create new inner list objects, it simply puts multiple references to the same list in the outer list. That is *always* how `n*[x]` works. EDIT: and because it does the looping in C, essentialyl pre-allocating the buffer and simply putting PyObject pointers in the buffer using a c-level loop. – juanpa.arrivillaga May 26 '22 at 23:38
  • @juanpa.arrivillaga Ahh that makes sense, so I guess there is no more optimal way to initialize that. Thank you for the explanation. –  May 26 '22 at 23:47

0 Answers0