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?
CodePudding user response:
You are adding the reference to the liat and not the actual list. Use instead
b.append(a[:])
CodePudding user response:
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.
CodePudding user response:
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.
CodePudding user response:
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]]