Создайте defaultdict со словарями в качестве записей по умолчанию с помощью фабричной функции - PullRequest
0 голосов
/ 19 апреля 2020

Я хочу Python 3 defaultdict со словарем в качестве записей. Предполагается, что это выглядит так:

my_dict[first_index] -> {second_index_1: value_1, second_index_2: value_2}

Как создать defaultdict описано в документации:

https://docs.python.org/3.6/library/collections.html#collections .defaultdict

Пример defaultdict с типом default int

d = defaultdict(int)

for k in s:

    d[k] += 1

Более сложные записи создаются с помощью фабричной функции (первый аргумент defaultdict должен вызываться ):

def constant_factory(value):

    return lambda: value

d = defaultdict(constant_factory('<missing>'))

Проблема в том, что функция constant_factory всегда возвращает идентичный dict при использовании, как указано выше:

def constant_factory(value):
    return lambda: value

my_dict = defaultdict(constant_factory({"second_index_1":None,"second_index_2":None}))

my_dict["first_index_1"]["second_index_1"] = "value_1"

приводит к:

my_dict["first_index_1"]["second_index_1"] -> "value_1"

как ожидается.

Теперь выполняем

def constant_factory(value):
    return lambda: value

my_dict = defaultdict(constant_factory({"second_index_1":None,"second_index_2":None}))

my_dict["first_index_1"]["second_index_1"] = "value_1"
my_dict["first_index_2"]["second_index_1"] = "value_2"

и получаем:

my_dict["first_index_1"]["second_index_1"] -> "value_2"

Это означает, что, получив доступ ко второй записи в dict, мы изменили первую случайно.

1 Ответ

0 голосов
/ 19 апреля 2020

Проблема заключается в фабричной функции, которая создает только один экземпляр:

def constant_factory(value):
    return lambda: value

Этого можно избежать, используя

def constant_factory(value):
    return lambda: value.copy()

При копировании dict каждый раз создается новый экземпляр ,

...