向字典中的一个列表添加值却将值添加到所有列表中

16 投票
1 回答
3938 浏览
提问于 2025-04-18 04:56

问题

我正在创建一个字典,里面的值是空列表,方法如下。

>>> 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 是一个不可变的对象,因此不会出现上述问题,因为对它的修改会生成新的对象,而不是改变底层的对象,这样不同的名称(在这个例子中是不同键的值)就不会共享同一个对象。

撰写回答