是否可以将here中讨论的方法扩展到嵌套的defaultdict?
编辑:
根据注释,默认值从原始的None
更新为lambda: None
。但是,以下内容仍然无法正常工作:
from collections import defaultdict
dd = defaultdict(lambda: None, {"a":1,"b":{"c":3}})
dd["b"]["e"]
引发KeyError
而不返回None。
如何将所有嵌套的dict转换为defaultdict?
答案 0 :(得分:2)
您可以这样做:
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
答案 1 :(得分:1)
collections.defaultdict
不是用于此目的的理想工具。要将None
指定为嵌套字典的默认值,只需找到iterate your dictionary recursively并使用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
答案 2 :(得分:0)
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]: ''
再次没有错误。 无论嵌套多少级。 弹出也没有错误 您可以根据需要将其更改为任何值。