Dict внутри defaultdict разделяется между ключами

У меня есть словарь внутри defaultdict. Я заметил, что словарь делится между ключами, поэтому он принимает значения последней записи. Как я могу выделить эти словари?

>>> from collections import defaultdict >>> defaults = [('a', 1), ('b', {})] >>> dd = defaultdict(lambda: dict(defaults)) >>> dd[0] {'a': 1, 'b': {}} >>> dd[1] {'a': 1, 'b': {}} >>> dd[0]['b']['k'] = 'v' >>> dd defaultdict(<function <lambda> at 0x7f4b3688b398>, {0: {'a': 1, 'b': {'k': 'v'}}, 1:{'a': 1, 'b': {'k': 'v'}}}) >>> dd[1]['b']['k'] = 'v2' >>> dd defaultdict(<function <lambda> at 0x7f4b3688b398>, {0: {'a': 1, 'b': {'k': 'v2'}}, 1: {'a': 1, 'b': {'k': 'v2'}}}) 

Обратите внимание, что для обоих словарей значение v установлено v2 . Почему это? и как изменить это поведение без значительных накладных расходов?

Когда вы делаете dict(defaults) вы не копируете внутренний словарь, просто ссылаетесь на него. Поэтому, когда вы меняете этот словарь, вы увидите это изменение везде, на которое оно ссылается.

Вам нужна deepcopy чтобы избежать проблемы:

 import copy from collections import defaultdict defaults = {'a': 1, 'b': {}} dd = defaultdict(lambda: copy.deepcopy(defaults)) 

Или вам не нужно использовать одни и те же внутренние изменяемые объекты при последовательных вызовах, не повторяя повторные ссылки на defaults :

 dd = defaultdict(lambda: {'a': 1, 'b': {}}) 

Все ваши значения содержат ссылки на один и тот же объект по defaults : вы перестраиваете внешний dict, но не внутренний. Просто создайте функцию, которая создает новый отдельный объект:

 def builder(): return {'a': 1, 'b': {}} dd = defaultdict(builder)