0
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?

martian03
  • 147
  • 1
  • 4

4 Answers4

0

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
Daniel
  • 3,228
  • 1
  • 7
  • 23
0
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']]
dishant makwana
  • 1,029
  • 6
  • 13
0
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.

Ref: Is there a difference between "==" and "is"?

Hoang Dung Pham
  • 366
  • 1
  • 5
0
  1. With a=[''*2] you will get [''] because empty string * 2 = empty string
  2. With a=['']*2 you will get ['','']
  3. With a=[['']*2] you will get [['','']]
  4. With a=[['']*2]*2 you will get [['', ''], ['', '']] Similar to step 2

What you used was a=[['']*2]*2 --> [['', ''], ['', '']] What you should have used was a = [[['']]*2]*2 --> [[[''], ['']], [[''], ['']]]

Anupam Chand
  • 2,209
  • 1
  • 5
  • 14