为了账号安全,请及时绑定邮箱和手机立即绑定

从 dict 构造一个嵌套的 defaultdict?

从 dict 构造一个嵌套的 defaultdict?

呼唤远方 2021-09-28 13:46:26
是否可以将此处讨论的方法扩展到嵌套的 defaultdict?编辑:根据评论,默认值从原始更新None为lambda: None. 但是,以下仍然无法按预期工作:from collections import defaultdictdd = defaultdict(lambda: None, {"a":1,"b":{"c":3}})dd["b"]["e"]引发一个KeyError而不是返回 None。如何将所有嵌套的 dict 转换为 defaultdict?
查看完整描述

3 回答

?
慕姐4208626

TA贡献1852条经验 获得超7个赞

你可以这样做:


from collections import defaultdict



def 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 result



d = {"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'])

输出


1

None

3

None


查看完整回答
反对 回复 2021-09-28
?
开心每一天1111

TA贡献1836条经验 获得超13个赞

collections.defaultdict不是用于此目的的理想工具。要将None嵌套字典指定为默认值,您可以递归地迭代您的字典,并在未找到任何级别的任何键时使用dict.get它返回None:


from functools import reduce


def 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'])  # None

get_from_dict(d, ['b', 'c'])  # 3


查看完整回答
反对 回复 2021-09-28
?
跃然一笑

TA贡献1826条经验 获得超6个赞

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 val



def _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 val



class 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]: ''

再次没有错误。无论嵌套多少层。弹出没有错误也可以根据需要更改为任何值。


查看完整回答
反对 回复 2021-09-28
  • 3 回答
  • 0 关注
  • 188 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信