是否可以将讨论的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?
发布于 2018-12-28 16:44:55
你可以这样做:
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发布于 2018-12-28 16:45:55
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发布于 2019-01-11 06:03:14
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]: ''不要再犯错误。不管嵌套了多少级别。弹出没有错误,也可以更改为任何值,如果你想。
https://stackoverflow.com/questions/53961347
复制相似问题