3 回答

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

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

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]: ''
再次没有错误。无论嵌套多少层。弹出没有错误也可以根据需要更改为任何值。
添加回答
举报