Double for loop giving unexpected answer

Question:

I have tested this example on both Python and JS, and since the result is the same only the former will be provided. Consider the snippet

a = []
b = []

for i in range(3):
   for j in range(2):
      a.append(0)
   print("a = ",a)

   b.append(a)
   print("b = ",b)

When done using a as a list, the result is [[0,0,0,0,0,0],[0,0,0,0,0,0],[0,0,0,0,0,0]]. If a is a string,

a = ""
b = []

for i in range(3):
   for j in range(2):
      a+= "0"
   print("a = ",a)

   b.append(a)
   print("b = ",b)

which gives ['00','0000','000000'].

When writing the code using lists, I was expecting the output [[0,0],[0,0,0,0],[0,0,0,0,0,0], similar to that of strings but in the shape of a list. I’ve been trying to wrap my head around this, but to no avail. What am I missing?

Asked By: miniplanck

||

Answers:

You are adding the reference to the list and not the actual list. Use instead

b.append(a[:])
Answered By: Yonatan Rubin

When a is a list, calling b.append(a) appends a reference to a to the end of b. Then the next time the for loop is is run, a changes and so all references to a within b also change.

Unlike lists, strings are immutable so b.append(a) appends a copy of a to the end of b. You can change your code to b.append(a[:]) to get the behavior you were looking for with strings, which makes a copy of a before appending.

Answered By: nikhilk

The issue is that a is a reference to the same array that is used in every loop. You’ve appended a to b, but you then in the next iteration reference the same a array.

b.append(list(a))

This makes a copy of the array you’re trying to append.

Answered By: CodeoftheWarrior

what you are missing -> how append works and what you are appending.

you are adding a reference to the b ie for each iteration your b look like

b = [reference_to_a, reference_to_a, referemce_to_a]

and finally the reference to a is the latest one ie of last iteration.

ie whatever the value be of laster iterabtion it will be same as for all values.

you can verify this by checking the id of object in all cases.

how to solve this -> use a deepcopy of a and append that or create a new list of a element.

you can verify this above statement

>>> a = [1]
>>> b = [1]
>>> 
>>> a.append(b)
>>> a.append(b)
>>> a.append(b)
>>> a.append(b)
>>> 
>>> a
[1, [1], [1], [1], [1]]
>>> 
>>> 
>>> b.append(2)
>>> a
[1, [1, 2], [1, 2], [1, 2], [1, 2]]

so to solbe this use

a.append(deepcopy(b))

you can verify this as

>>> 
>>> a =[1]
>>> b = [1]
>>> 
>>> from copy import deepcopy
>>> 
>>> a.append(deepcopy(b))
>>> a
[1, [1]]
>>> b
[1]
>>> b.append(3)
>>> a
[1, [1]]
>>> b
[1, 3]
>>> a.append(deepcopy(b))
>>> a
[1, [1], [1, 3]]
>>> b.append(5)
>>> a
[1, [1], [1, 3]]
>>> a.append(deepcopy(b))
>>> a
[1, [1], [1, 3], [1, 3, 5]]
Answered By: sahasrara62
Categories: questions Tags: , , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.