Python字典行为疑问:为何修改一个值会影响所有关联列表?
为什么字典中两个键对应的列表会同时被修改?
先来看你给出的这段代码:
x = [0, 1] y = [[]]*2 z = dict(zip(x, y)) print(z) # {0: [], 1: []} z[0].append(0) print(z) # {0: [0], 1: [0]}
你疑惑为什么修改z[0]的列表后,z[1]的列表也跟着变了?核心问题出在这行代码上:y = [[]]*2。
关键原因:列表乘法的引用陷阱
当你用[[]]*2创建列表时,并不是生成两个独立的空列表,而是把同一个空列表对象的引用复制了两次。也就是说,y[0]和y[1]指向的是内存中的同一个列表。你可以用id()函数验证一下:
y = [[]]*2 print(id(y[0]) == id(y[1])) # 输出True,说明是同一个对象
当你通过zip(x, y)创建字典z时,z[0]和z[1]其实都是指向这个同一个列表的引用。所以不管你是调用z[0].append(0)还是z[1].append(0),本质上都是在修改同一个底层列表,自然两个键对应的列表都会显示出变化。
为什么不用zip时操作正常?
假设你不用zip,直接这样创建字典:
z = {0: [], 1: []}
这时候z[0]和z[1]是两个完全独立的空列表对象,它们的内存地址不同,修改其中一个当然不会影响另一个。
怎么解决这个问题?
如果想创建包含独立空列表的y,可以用列表推导式:
y = [[] for _ in range(2)]
这样每次循环都会生成一个新的空列表,y[0]和y[1]就是两个独立的对象了,再用zip创建字典,修改其中一个列表就不会影响另一个了。
内容的提问来源于stack exchange,提问作者Peri Javia
相关产品推荐
相关产品推荐

