Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Simple python code about double loop

Tags:

python

I tested the following python code on Spyder IDE. Thinking it would output 2d array q as increasing number as 0..31 from q[0][0] to q[3][7]. But it actually returns q as:

[[24, 25, 26, 27, 28, 29, 30, 31], [24, 25, 26, 27, 28, 29, 30, 31], [24, 25, 26, 27, 28, 29, 30, 31], [24, 25, 26, 27, 28, 29, 30, 31]]. 

The code:

q=[[0]*8]*4 
for i in range(4): 
    for j in range(8): 
        q[i][j] = 8*i+j 
print q

Any idea of what's happening here? I debugged step by step. It shows the updates of every row will sync with all other rows, quite different from my experience of other programing languages.

like image 783
user1640608 Avatar asked Jan 28 '26 11:01

user1640608


2 Answers

q=[somelist]*4 

creates a list with four identical items, the list somelist. So, for example, q[0] and q[1] reference the same object.

Thus, in the nested for loop q[i] is referencing the same list regardless of the value of i.

To fix:

q = [[0]*8 for _ in range(4)]

The list comprehension evaluates [0]*8 4 distinct times, resulting in 4 distinct lists.


Here is a quick demonstration of this pitfall:

In [14]: q=[[0]*8]*4

You might think you are updating only the first element in the second row:

In [15]: q[1][0] = 100

But you really end up altering the first element in every row:

In [16]: q
Out[16]: 
[[100, 0, 0, 0, 0, 0, 0, 0],
 [100, 0, 0, 0, 0, 0, 0, 0],
 [100, 0, 0, 0, 0, 0, 0, 0],
 [100, 0, 0, 0, 0, 0, 0, 0]]
like image 127
unutbu Avatar answered Jan 31 '26 00:01

unutbu


As explained the problem is caused due to * operation on lists, which create more references to the same object. What you should do is to use append:

q=[]
for i in range(4): 
    q.append([])
    for j in range(8): 
        q[i].append(8*i+j)
print q 

[[0, 1, 2, 3, 4, 5, 6, 7], [8, 9, 10, 11, 12, 13, 14, 15], [16, 17, 18, 19, 20, 21, 22, 23], [24, 25, 26, 27, 28, 29, 30, 31]]

like image 37
zenpoy Avatar answered Jan 31 '26 00:01

zenpoy



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!