向字典中的一个列表添加值却将值添加到所有列表中
问题
我正在创建一个字典,里面的值是空列表,方法如下。
>>> words = dict.fromkeys(['coach', 'we', 'be'], [])
这个字典看起来是这样的。
>>> words
{'coach': [], 'be': [], 'we': []}
当我往其中一个列表里添加一个值时,这个值却被添加到了所有的列表里,就像这个例子一样。
>>> words['coach'].append('test')
{'coach': ['test'], 'be': ['test'], 'we': ['test']}
我的疑问
我的问题有两个部分。首先,为什么会发生这种情况?其次,我该怎么做?也就是说,我怎么才能只往一个列表里添加值?
我想在创建字典的时候,所有的列表都指向了同一个对象。但我不明白为什么会这样,因为当我在创建字典时输入0
而不是[]
,然后添加值而不是追加值时,这些值的表现又像是指向了不同的对象。
我很感激任何建议。提前谢谢你!
1 个回答
25
dict.fromkeys
方法会为所有的键使用同一个对象,在这个例子中是一个 可变
的列表。这意味着,所有的键都共享同一个空列表。当你对其中一个列表的值使用 .append
方法时,实际上是在原地修改这个对象,所以所有引用这个对象的地方都会看到这个变化。
如果你使用字典推导式,比如 {k:[] for k in ['could', 'we', 'be']}
,那么每个 []
都是一个不同的空列表,这样每个键的值都是独一无二的,效果就会如你所愿。
关于使用 dict.fromkeys(['a', 'b', 'c'], 0)
,这里的 0
是一个不可变的对象,因此不会出现上述问题,因为对它的修改会生成新的对象,而不是改变底层的对象,这样不同的名称(在这个例子中是不同键的值)就不会共享同一个对象。