That's because :
alist =[[0,0,0]]*10
is not the same as alist = [[0,0,0], [0,0,0], [0,0,0], [0,0,0], [0,0,0], [0,0,0], [0,0,0], [0,0,0], [0,0,0], [0,0,0]]
In your assignment you are just creating a list of 10 duplicates of the same item [0,0,0]
, so any change to one of them will be reflected to the remaining 9.
See below demonstration:
>>> x = [0,0,0]
>>> id(x)
140348692006664
>>>
>>>
>>> l1 = [x]*10
>>> l2 = [[0,0,0], [0,0,0], [0,0,0], [0,0,0], [0,0,0], [0,0,0], [0,0,0], [0,0,0], [0,0,0], [0,0,0]]
>>>
>>>
>>> for i in l1:
print(id(i))
140348692006664
140348692006664
140348692006664
140348692006664
140348692006664
140348692006664
140348692006664
140348692006664
140348692006664
140348692006664
>>>
>>>
>>> for j in l2:
print(id(j))
140348692008712
140348692008648
140348691779528
140348692008520
140345708853320
140348692007688
140348691927176
140348691829640
140348691831112
140345708570760
And secondly, alist
is a list of mutable objects(list) so, any change in any one of them will be reflected to the other due to the nature of your assignment (alist = [[0,0,0]]*10
), whereas blist
is a list of immutable objects(list of integer 0), so when you do blist[i]=i
you are not changing the value but creating a new reference to the new object.
>>> l4 = ['1']*10 #list of immutable objects
>>> l4
['1', '1', '1', '1', '1', '1', '1', '1', '1', '1']
>>>
>>>
>>> l4[0]='0'
>>> l4
['0', '1', '1', '1', '1', '1', '1', '1', '1', '1'] #only first item affected
>>>
>>> l5 = [{1:'1'}]*10 #list of mutable objects
>>>
>>> l5
[{1: '1'}, {1: '1'}, {1: '1'}, {1: '1'}, {1: '1'}, {1: '1'}, {1: '1'}, {1: '1'}, {1: '1'}, {1: '1'}]
>>>
>>> l5[0][1] = 'ONE'
>>>
>>> l5
[{1: 'ONE'}, {1: 'ONE'}, {1: 'ONE'}, {1: 'ONE'}, {1: 'ONE'}, {1: 'ONE'}, {1: 'ONE'}, {1: 'ONE'}, {1: 'ONE'}, {1: 'ONE'}] #all affected