Python坑-两种不同二维列表生成的差异

利用 *符号生成的二维列表和基于列表推导式生成的二维列表的差异.

a = [[1] * 5] * 5
a
[[1, 1, 1, 1, 1],
 [1, 1, 1, 1, 1],
 [1, 1, 1, 1, 1],
 [1, 1, 1, 1, 1],
 [1, 1, 1, 1, 1]]
b = [[1 for _ in range(5)] for _ in range(5)]
b
[[1, 1, 1, 1, 1],
 [1, 1, 1, 1, 1],
 [1, 1, 1, 1, 1],
 [1, 1, 1, 1, 1],
 [1, 1, 1, 1, 1]]

a, b两种方式开起来是一样的, 都是生成二维数组, 但 ... ? 是否存在差异呢?

a[0][0] = 10
a
[[10, 1, 1, 1, 1],
 [10, 1, 1, 1, 1],
 [10, 1, 1, 1, 1],
 [10, 1, 1, 1, 1],
 [10, 1, 1, 1, 1]]

a只要修改其中的一个值, 其他的数据会同时改变

b[0][0] = 10
b
[[10, 1, 1, 1, 1],
 [1, 1, 1, 1, 1],
 [1, 1, 1, 1, 1],
 [1, 1, 1, 1, 1],
 [1, 1, 1, 1, 1]]

b修改只会修改对应的值

for e in a:
    print(id(e))
2995316327104
2995316327104
2995316327104
2995316327104
2995316327104

使用 "*" 符号生成的二维列表, 是共享内存地址的

for e in b:
    print(id(e))
2995320755392
2995320779584
2995320353600
2995320301248
2995321229248