如何将嵌套字典转换为嵌套 defaultdict?

dic = {"a": {"aa": "xxx"}}
default = defaultdict(lambda: None, dic)
print(default["dummy_key"])  # return None
print(default["a"]["dummy_key"])  # KeyError

最佳答案

您需要在嵌套字典的所有级别上循环或递归。

除非它可能非常深(如数百个级别),或者太宽以至于小的性能因素会产生影响,否则递归在这里可能是最简单的:

def defaultify(d):
    if not isinstance(d, dict):
        return d
    return defaultdict(lambda: None, {k: defaultify(v) for k, v in d.items()})

或者,如果您希望它适用于所有映射,而不仅仅是字典,您可以在 collections.abc.Mapping 检查中使用 dict 而不是 isinstance

当然,这是假设您有一个纯嵌套的 dict。例如,如果您从典型的 JSON 响应中解析出某些内容,其中可能有带有 dict 元素的列表值的 dict,那么您也必须处理其他可能性:
def defaultify(d):
    if isinstance(d, dict):
        return defaultdict(lambda: None, {k: defaultify(v) for k, v in d.items()})
    elif isinstance(d, list):
        return [defaultify(e) for e in d]
    else:
        return d

但如果这实际上来自 JSON,那么在解析 JSON 时将 defaultdict 用作 object_pairs_hook 可能更好,而不是将其解析为 dict,然后再将其转换为 defaultdict。

文档中有一个使用 OrderedDict 代替 dict 的示例,但这对我们来说不太适用——与 OrderedDictdict 不同,defaultdict 不能只将可迭代的对作为其唯一参数;它首先需要默认值工厂。所以我们可以使用 functools.partial 绑定(bind)它:
d = json.loads(jsonstring, object_hook_pairs=partial(defaultdict, lambda: None))

等等。

关于python - 如何将嵌套字典转换为 defaultdict?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/50013768/

10-12 23:30