Sometimes, we need to initialize a list with a certain number of nested lists, for example, a list with 3 lists of length 3 that can represent a Tic-tac-toe board.
>>> board = [[''] * 3] * 3
>> board
[['', '', ''], ['', '', ''], ['', '', '']]
>> board[1][2] = 'X'
>> board
[['', '', 'X'], ['', '', 'X'], ['', '', 'X']]
The output is not expected, why?
Because the outer list is made of three references to the same inner list, a fact that you can see from id(board[0]) == id(board[1]) is True. While it is unchanged, all seems right. After placing a mark in row 1, column 2, it reveals that all rows are alias referring to the same object.
In essence, the above code behaves like:
row = [''] * 3
board = []
for _ in range(3):
board.append(row)
It is much obvious that the same row is appended 3 times to board.
The correct way to achieve our goal is:
>>> board = [[''] * 3 for _ in range(3)]
>> board
[['', '', ''], ['', '', ''], ['', '', '']]
>> board[1][2] = 'X'
>> board
[['', '', ''], ['', '', 'X'], ['', '', '']]
Actually, it is equivalent to this code:
board = []
for _ in range(3):
row = [''] * 3
board.append(row)
Reference