Home > Enterprise >  Python for loop glitching out
Python for loop glitching out

Time:01-18

My program starts off like this

array=[[[0,0]]*4]*4
for i in range(4):
    for k in range(4):
        array[i][k]=[i,k]

for n in range(4):
    print(array[n])

but outputs this

[[3, 0], [3, 1], [3, 2], [3, 3]]
[[3, 0], [3, 1], [3, 2], [3, 3]]
[[3, 0], [3, 1], [3, 2], [3, 3]]```

I'm using 3.11, I tried switching i and k around, switching the names for the variables, doing


array[i][k][0]=k array[i][k][1]=i

etc. but none of it has worked. I want it to output 
```[[0, 0], [0, 1], [0, 2], [0, 3]]
[[1, 0], [1, 1], [1, 2], [1, 3]]
[[2, 0], [2, 1], [2, 2], [2, 3]]
[[3, 0], [3, 1], [3, 2], [3, 3]]```

CodePudding user response:

This can also be thought as the cartesian product of two arrays [0, 1, 2, 3]. You can use itertools.product to achieve this pretty easily.

import itertools 

list(itertools.product([0, 1, 2, 3], [0, 1, 2, 3]))

Returns

[(0, 0), (0, 1), (0, 2), (0, 3), 
 (1, 0), (1, 1), (1, 2), (1, 3), 
 (2, 0), (2, 1), (2, 2), (2, 3), 
 (3, 0), (3, 1), (3, 2), (3, 3)]

It's also the equivalent of just doing:

[[x, y] for x in [0, 1, 2, 3] for y in [0, 1, 2, 3]]
[[0, 0], [0, 1], [0, 2], [0, 3], 
 [1, 0], [1, 1], [1, 2], [1, 3], 
 [2, 0], [2, 1], [2, 2], [2, 3], 
 [3, 0], [3, 1], [3, 2], [3, 3]]

CodePudding user response:

array = [[[0, 0]] * 4] * 4

You think you have many independent lists of zero-pairs.

But really there's just a small number of lists with a bunch of pointers to them. That is, each assignment updates a single list element, but because multiple outer lists point at the container, the update appears to affect multiple locations.


You would be happier with pip install numpy (import numpy as np) and assigning

array = np.array([[[0, 0]] * 4] * 4)

That will allocate separate integer storage for each cell, and you can update them independently to your heart's content, without surprises.


Here is a simpler demonstration of the effect you were seeing.

>>> a = b = c = [5, 6, 7, 8]
>>> a
[5, 6, 7, 8]
>>> b
[5, 6, 7, 8]
>>> c
[5, 6, 7, 8]
>>> 
>>> 
>>> a[1] = 1
>>> 
>>> a
[5, 1, 7, 8]
>>> 
>>> b
[5, 1, 7, 8]
>>> 
>>> c
[5, 1, 7, 8]

Notice that b is a pointer to the same list as a, and likewise c.

There's just a single list, and it doesn't have a single name. In a sense any of those three names is equally valid. We have three references to the identical underlying list.

  • Related