Introduction

In the following example X is assigned to L repeated four times, whereas Y is assigned to a list containing L repeated four times:

Demo

L = [4, 5, 6] 
X = L * 4                   # Like [4, 5, 6] + [4, 5, 6] + ... 
Y = [L] * 4                 # [L] + [L] + ... = [L, L,...] 
#   w w  w . j  a  va 2  s.co m
print( X )
print( Y )

Result

Because L was nested in the second repetition, Y winds up embedding references back to the original list assigned to L.

Demo

L = [4, 5, 6] 
X = L * 4                   # Like [4, 5, 6] + [4, 5, 6] + ... 
Y = [L] * 4                 # [L] + [L] + ... = [L, L,...] 
# from  w  w  w .j a v a  2  s .co  m
print( X )
print( Y )

L[1] = 0                    # Impacts Y but not X 
print( X )
print( Y )

Result

To create the shared mutable object reference case: make copies when you don't want shared references:

Demo

L = [4, 5, 6] 
Y = [list(L)] * 4           # Embed a (shared) copy of L 
L[1] = 0 # from ww w.j a  va2 s.  co m
print( Y )

Result

To avoid sharing, make sure each embedded copy is unique:

Demo

L = [4, 5, 6] 
Y = [list(L)] * 4           # Embed a (shared) copy of L 
#  w  w w .  j  av a  2s.  c o  m
Y[0][1] = 99                # All four copies are still the same 
print( Y )

L = [4, 5, 6] 
Y = [list(L) for i in range(4)] 
print( Y )
Y[0][1] = 99 
print( Y )

Result

Repetition, concatenation, and slicing copy only the top level of their operand objects.

Related Topic