相同列表功能的输出不同

为什么输出不同?

n = 5

##################################

dp  = [[False]*n]*n

# make diagonal True 
for i in range(n): dp[i][i] = True

print("CASE #1")
for i in dp: print(i)

##################################

dp = [[False for i in range(n)] for j in range(n)]

# make diagonal True 
for i in range(n): dp[i][i] = True

print("CASE #2")
for i in dp: print(i)
CASE #1
[True, True, True, True, True]
[True, True, True, True, True]
[True, True, True, True, True]
[True, True, True, True, True]
[True, True, True, True, True]
CASE #2
[True, False, False, False, False]
[False, True, False, False, False]
[False, False, True, False, False]
[False, False, False, True, False]
[False, False, False, False, True]

I am not able to justify the output for case 1. Is it one pointer/reference (n size array of False) that is copied n times? Can someone explain how is dp created in the first case?