Рекурсивная инициализация collection.defaultdict - PullRequest
0 голосов
/ 08 января 2019

Моя цель состоит в том, чтобы, учитывая диктант python, который я называю datainit, создать рекурсив collections.defaultdict, который я называю data, например, data инициализируется с помощью datainit, и data может быть расширены с любым путем пропущенных ключей, как показано ниже

from collections import *
datainit={'number':1}
data =something_with(defaultdict(), datainit)
data['A']['B']['C']=3
#At this stage, I want:
#data['A']['B']['C'] ==3
#data['number'] == 1
#and nothing else.

Обычный способ сделать это, начиная с пустого слова, например:

nested_dict = lambda: defaultdict(nested_dict)
data = nested_dict()

Попытка:

nested_dict = lambda: defaultdict(nested_dict, datainit)
data = nested_dict()

Логически приведет к тому, что мои данные будут дублироваться для каждого отсутствующего ключа:

>>> datainit={'number':1}
>>> nested_dict = lambda: defaultdict(nested_dict, datainit)
>>> data=nested_dict()
>>> data
defaultdict(<function <lambda> at 0x7f58e5323758>, {'number': 1})
>>> data['A']['B']['C']=2
>>> data
defaultdict(<function <lambda> at 0x7f58e5323758>, {'A': defaultdict(<function <lambda> at 0x7f58e5323758>, {'B': defaultdict(<function <lambda> at 0x7f58e5323758>, {'C': 2, 'number': 1}), 'number': 1}),
'number': 1})

Все это имеет смысл, но как мне сделать, чтобы просто начать с начального dict, а затем просто использовать пустой dict для каждого недостающего ключа? Каким должен быть мой something_with(defaultdict(), datainit).

Вероятно, очевидно, но я не вижу этого!

1 Ответ

0 голосов
/ 08 января 2019

У вас есть два уровня; верхний уровень defaultdict, который должен иметь ключ number, и ряд произвольно вложенных словарей, которых не должно быть. Ваша ошибка состоит в том, чтобы попытаться обработать их как единое целое, и , чтобы попытаться обработать 'number' как нечто, с чем должна справиться фабрика пропущенных значений.

Просто установите ключ number в верхнем словаре. Существует только один такой ключ со значением, и не должен обрабатываться фабрикой defaultdict(). Фабрика предоставляет значение по умолчанию для произвольных пропущенных ключей, number не является произвольным ключом.

from collections import defaultdict

def topleveldict():
    nested_dict = lambda *a, **kw: defaultdict(nested_dict, *a, **kw)
    return nested_dict(number=1)  # or nested_dict({'number': 1})

data = topleveldict()

Функция topleveldict() необходима только в том случае, если вы планируете создать структуру в нескольких местах в вашей кодовой базе. Если есть только один такой объект или только одно место, где вы их создаете, просто вставьте код из этой функции:

nested_dict = lambda *a, **kw: defaultdict(nested_dict, *a, **kw)
data = nested_dict(number=1)  # or nested_dict({'number': 1})
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...