如何屏蔽Python 3嵌套字典以返回仅包含特定项的新字典?

Tod*_*odd 8 python dictionary iterator

我正在使用API​​的几个端点,它返回的数据非常冗长.我想将这些数据的一部分提供给其他地方的另一段代码.

假设我有几个这样的字典(我计划循环并过滤):

asset = {
    'id': 1,
    'name': 'MY-PC',
    'owner': 'me',
    'location': 'New York City',
    'model': {
        'id': 1,
        'name': 'Surface',
        'manufacturer': {
            'id': 1,
            'name': 'Microsoft'
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我想创建一个将该字典带入的函数,以及一个"掩码",它将用于创建仅允许的项目的新字典.这可能是一个示例掩码(但是,我可以使用任何格式使得生成的代码最简洁):

mask = {
    'id': True,
    'name': True,
    'model': {
        'id': True,
        'name': True,
        'manufacturer': {
            'name': True
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

然后该函数应该返回:

mask = {
    'id': 1,
    'name': 'MY-PC',
    'model': {
        'id': 1,
        'name': 'Surface',
        'manufacturer': {
            'name': 'Microsoft'
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

Python 3中是否已经内置了有助于此的内容?看起来如果我必须手动执行此操作,它会很快变得非常难看.我发现itertools.compress,但这似乎是列表,不会处理字典的复杂性.

Mos*_*oye 5

您可以通过仅选择主字典中对应的值来从掩码递归构建新字典:

def prune_dict(dct, mask):
    result = {}
    for k, v in mask.items():
        if isinstance(v, dict):
            value = prune_dict(dct[k], v)
            if value: # check that dict is non-empty
                result[k] = value
        elif v:
            result[k] = dct[k]
    return result

print(prune_dict(asset, mask))
Run Code Online (Sandbox Code Playgroud)
{'id': 1,
'model': {'id': 1, 'manufacturer': {'name': 'Microsoft'}, 'name': 'Surface'},
'name': 'MY-PC'}
Run Code Online (Sandbox Code Playgroud)