从 dict 构造一个嵌套的 defaultdict?

是否可以将此处讨论的方法扩展到嵌套的 defaultdict?


编辑:


根据评论,默认值从原始更新None为lambda: None. 但是,以下仍然无法按预期工作:


from collections import defaultdict

dd = defaultdict(lambda: None, {"a":1,"b":{"c":3}})

dd["b"]["e"]引发一个KeyError而不是返回 None。


如何将所有嵌套的 dict 转换为 defaultdict?


呼唤远方
浏览 288回答 3
3回答

慕姐4208626

你可以这样做:from collections import defaultdictdef to_none(d, factory):    result = defaultdict(factory)    for key, value in d.items():        if isinstance(value, dict):            result[key] = to_none(value, factory)        else:            result[key] = value    return resultd = {"a": 1, "b": {"c": 3}}dd = to_none(d, lambda: None)print(dd['a'])print(dd['xxx'])print(dd['b']['c'])print(dd['b']['e'])输出1None3None

开心每一天1111

collections.defaultdict不是用于此目的的理想工具。要将None嵌套字典指定为默认值,您可以递归地迭代您的字典,并在未找到任何级别的任何键时使用dict.get它返回None:from functools import reducedef get_from_dict(dataDict, mapList):    """Iterate nested dictionary"""    return reduce(dict.get, mapList, dataDict)d = {"a": 1, "b": {"c": 3}}get_from_dict(d, ['b', 'e'])  # Noneget_from_dict(d, ['b', 'c'])  # 3

跃然一笑

def _sub_getitem(self, k):    try:        # sub.__class__.__bases__[0]        real_val = self.__class__.mro()[-2].__getitem__(self, k)        val = '' if real_val is None else real_val    except Exception:        val = ''        real_val = None    # isinstance(Avoid,dict)也是true,会一直递归死    if type(val) in (dict, list, str, tuple):        val = type('Avoid', (type(val),), {'__getitem__': _sub_getitem, 'pop': _sub_pop})(val)        # 重新赋值当前字典键为返回值,当对其赋值时可回溯        if all([real_val is not None, isinstance(self, (dict, list)), type(k) is not slice]):            self[k] = val    return valdef _sub_pop(self, k=-1):    try:        val = self.__class__.mro()[-2].pop(self, k)        val = '' if val is None else val    except Exception:        val = ''    if type(val) in (dict, list, str, tuple):        val = type('Avoid', (type(val),), {'__getitem__': _sub_getitem, 'pop': _sub_pop})(val)    return valclass DefaultDict(dict):    def __getitem__(self, k):        return _sub_getitem(self, k)    def pop(self, k):        return _sub_pop(self, k)In[8]: d=DefaultDict({'balabala':"dddddd"})In[9]: d['a']['b']['c']['d']Out[9]: ''In[10]: d['a']="ggggggg"In[11]: d['a']Out[11]: 'ggggggg'In[12]: d['a']['pp']Out[12]: ''再次没有错误。无论嵌套多少层。弹出没有错误也可以根据需要更改为任何值。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Python