a=[['']*2]*2
a[0][1]='previous'
a[1][1]='new'
print(a[0][1])
The result of this code is 'new' instead of 'previous'. When I changed the declaration of list as a=[ [[''],['']], [[''],['']] ] now it is okay. But why difference?
Okay, let's assume a == b. Multiplying a list by (case a) 2 creates a deep copy, i.e. memory addresses are shared. Constructing a list by hand (case b) avoids this issue. Hence when you access and updates elements within a you are actually updating both inner lists:
a = [['']*2]*2
b = [['', ''], ['', '']]
print(a == b) # True
print(a)
a[0][1] = 'previous'
print(a)
print(id(a[0]) == id(a[1])) # True, same memory address
print(b)
b[0][1] = 'previous'
print(b)
print(id(b[0]) == id(b[1])) # False, different memory addresses
a=[['']*2]*2
above can be broken down into:
a = ['']*2 #result: a = ['', ''] --> it copies value of '' since '' is a string
a = [a]*2 #result: a = [a,a] --> which means it copies the reference of a instead of its value since a is a list.
a[0][1]='previous' # result: [['', 'previous'], ['', 'previous']]
a = [['']*2]*2
print (a[0][1] is a[1][1]) # true
So when you declare an array, the element in array should be different reference object.
What you used was a=[['']*2]*2 --> [['', ''], ['', '']] What you should have used was a = [[['']]*2]*2 --> [[[''], ['']], [[''], ['']]]