Это потому, что:
alist =[[0,0,0]]*10
не то же самое, как 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]]
В вашем задании вы просто создаете список из 10 дублей одного и того же элемента [0,0,0]
, так что любое изменение одного из них будут отражены к оставшемуся 9.
ниже демонстрации:
>>> 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
Во-вторых, alist
- это список изменяемых объектов (список), поэтому любое изменение в любом из них будет отражено в другом из-за характера вашего назначения (alist = [[0,0,0]]*10
), тогда как blist
- это список неизменяемых объектов (список от целого числа 0), поэтому, когда вы делаете blist[i]=i
, вы не меняете значение, а создаете новую ссылку на новый объект.
>>> 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
Это, вероятно, то же самое [в этом вопросе] (http://stackoverflow.com/questions/240178/python-list-of-lists-changes-reflected-across- sublists-неожиданно) – syntonym