Добавление значения в один список в словаре добавляет значение ко всем спискам в словаре

Проблема

Я создаю словарь с пустыми списками как значения следующим образом.

>>> words = dict.fromkeys(['coach', 'we', 'be'], [])

Словарь выглядит следующим образом.

>>> words
{'coach': [], 'be': [], 'we': []}

Когда я добавляю значение в один список, это значение добавляется ко всем из них, как в этом примере.

>>> words['coach'].append('test')
{'coach': ['test'], 'be': ['test'], 'we': ['test']}

Вопрос

Мой вопрос состоит из двух частей. Во-первых, почему это происходит? Во-вторых, что я могу сделать? То есть, как я могу добавить значение только к одному списку?

Я предполагаю, что при создании словаря я сделал все списки, указывающие на один и тот же объект. Но я не понимаю, как это может быть из-за того, что когда я ввожу 0 вместо [] в создание словаря, а затем добавляю значения вместо их добавления, значения ведут себя по-другому, как если бы они указывали на разные объекты.

Буду признателен за любой ввод. Заранее благодарю вас!

Ответ 1

dict.fromkeys использует один и тот же объект для всех значений, в этом случае список mutable... Это означает, что все ключи имеют один и тот же пустой список... Когда вы пытаетесь выполнить .append значение одного список, изменения сделаны на месте для объекта, поэтому изменения в нем видны всем, что ссылается на него.

Если вместо этого вы использовали dict-comp, например: {k:[] for k in ['could', 'we', 'be']}, каждый [] является другим пустым списком и поэтому будет уникальным для каждого значения ключа и будет работать как ожидалось.

Что касается использования dict.fromkeys(['a', 'b', 'c'], 0), то 0 является неизменным объектом, поэтому он не подпадает под эту информацию, поскольку изменения в нем приводят к появлению новых объектов, а не к изменению базового объекта, в котором разные имена (в данном случае - значения разных ключей) могут делиться.