note from:
preview
Cpython 在编译优化时, 某些情况下会尝试
使用已经存在的不可变对象
而不是每次都创建一个新对象. 这种行为被称作字符串的驻留[string interning]
在下面两份代码中,小列表中的元素
符合字符串的要求,编译器已经给这些字符串分配好房间
代码_2<大列表中的小列表在不同的内存地址>:
board_after=[['']*3 for _ in range(3)] # 先生成三个小列表,然后把放在大列表中
for i in board_after:
print(id(i[0]),id(i[2]),id(i[1]))
print('-------')
board_after[0][0]='x' # 指向另一个内存地址
board_after[0][1]='y'
for i in board_after:
print(id(i[0]),id(i[2]),id(i[1]))
board_after
输出结果_2:
139698166676144 139698166676144 139698166676144
139698166676144 139698166676144 139698166676144
139698166676144 139698166676144 139698166676144
-------
`139698166356376` 139698166676144 `139698142845560`
139698166676144 139698166676144 139698166676144
139698166676144 139698166676144 139698166676144
[['x', 'y', ''], ['', '', ''], ['', '', '']]
a='y'
id(a) # 139698142845560 # 再看看上面的代码,是不是内存地址一致呢?------发生字符串驻留
代码_2 图例:
代码_1<大列表中的小列表在相同的内存地址>:
row=['']*3 # 先生成一个小列表,里头三个空格
for i in row:
print(id(i))
board=[row]*3 # 然后利用自乘复制
for i in board:
print(id(i[0]),id(i[2]),id(i[1])) # 三个小列表中的元素全部都来自同一个内存地址
print('----')
board[0][0]='y' # 直接对该内存地址修改
print(board)
for i in board:
print(id(i[0]),id(i[2]),id(i[1])) # 三个小列表中的元素全部都来自同一个内存地址
输出结果_1:
139698166676144
139698166676144
139698166676144
139698166676144 139698166676144 139698166676144
139698166676144 139698166676144 139698166676144
139698166676144 139698166676144 139698166676144
----
[['y', '', ''], ['y', '', ''], ['y', '', '']]
139698142845560 139698166676144 139698166676144
139698142845560 139698166676144 139698166676144
139698142845560 139698166676144 139698166676144
代码_1 图例: