简体   繁体   English

递归 collections.defaultdict 初始化

[英]Recursive collections.defaultdict initialization

My goal is to, given a python dict which I call datainit , create a recursive collections.defaultdict which I call data , such as data is initialised with datainit , and data can be extended with any path of missing keys, as illustrated below我的目标是,给定一个我称之为datainit的 python dict,创建一个递归的collections.defaultdict ,我称之为data ,例如datadatainit初始化,并且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.

The normal way to do that starting with an empty dict is, for instance:例如,从空字典开始执行此操作的正常方法是:

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

Trying:试:

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

Will logically result in my datainit being duplicated for each missing key:逻辑上会导致我的 datainit 为每个丢失的键复制:

>>> 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})

All this makes sense, but how do I do to just start with an initial dict and then just use an empty dict for each missing keys?所有这些都是有道理的,但是我该怎么做才能从初始字典开始,然后为每个缺少的键使用一个空字典? What should be my something_with(defaultdict(), datainit) .我的something_with(defaultdict(), datainit)应该是something_with(defaultdict(), datainit)

Probably obvious, but I cannot see it!可能很明显,但我看不到它!

You have two tiers;你有两层; the top level defaultdict , which must have the number key, and a series of arbitrarily nested dictionaries, which must not.顶级defaultdict ,必须有number键,以及一系列任意嵌套的字典,但不能。 Your mistake is to try to treat these as one, and to try to treat 'number' as something the factory for missing values should handle.你的错误是尝试将这些视为一个,尝试将'number'视为缺失值工厂应该处理的东西。

Just set the number key in the top dictionary.只需在顶级字典中设置number键即可。 There is just one such key, with a value, and it should not be handled by the defaultdict() factory.只有一个这样的键,有一个值,它应该由defaultdict()工厂处理。 The factory is there to provide a default value for arbitrary missing keys, number is not an arbitrary key.工厂为任意丢失的键提供默认值, 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()

The topleveldict() function is only needed if you plan to create the structure in multiple places in your codebase.仅当您计划在代码库中的多个位置创建结构时,才需要topleveldict()函数。 If there is just one such object or just one place you create these, then just inline the code from that function:如果只有一个这样的对象或只有一个地方创建这些对象,那么只需内联该函数中的代码:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM