从展平嵌套字典的映射创建新字典

时间:2015-04-06 08:47:20

标签: python dictionary nested flatten

我想知道是否有快速和pythonic的方式来创建基于字典的某些键的字典?

例如,如果我有这个给定的字典

{
  "a": "abc",
  "b": {"b1": "1", "b2": "2", "b3": "3"},
  "c": 1,
  "d": "timmy",
  "e": "John"
}

我希望能够基于给定字典的几个键创建一个具有一对一映射的新字典。因此,在此示例中,我想仅基于键"b2""c""d"创建字典。我也想给这些键赋一个不同的名字。所需的输出是:

{
  "out_b2": "2",
  "out_c": 1,
  "out_d": "timmy"
}

我能想到的最简单的过程是创建嵌套for循环来执行此任务。我想知道是否有更有效的方法来实现这一目标。

据我所知,根据投入和产出的情况,他的问题可能会令人困惑。让我们保持简单,并说最深层次是输入的一个子字典的最大值,输出将没有任何子域

2 个答案:

答案 0 :(得分:2)

您可以遍历字典项并检查该值是否为dict再次循环其项目,并检查该键是否在您指定的键中,然后将该项添加到新词典中:

>>> old={
...   "a": "abc",
...   "b": {"b1": "1", "b2": "2", "b3": "3"},
...   "c": 1,
...   "d": "timmy",
...   "e": "John"
... }
>>> new={}
>>> for i, j in old.items():
...    if i in key:
...        new['out_'+i]=j
...    elif isinstance(j,dict):
...         for k, v in j.items():
...              if k in key:
...                   new['out_'+k]=v
... 
>>> new
{'out_d': 'timmy', 'out_b2': '2', 'out_c': 1}

答案 1 :(得分:1)

我会使用另一个字典来保存从旧名称到所需名称的映射:

mappings = {
    'b.b2': 'out_b2',
    'c': 'out_c',
    'd': 'out_d',
}

我在密钥中使用.来表示嵌套字典的子密钥 - 如果密钥中可能包含.,请使用不同的分隔符(a /,说)。我使用辅助函数将虚线子标记符号转换为值:

def get_node(d, path):
    if '.' not in path:
        return d[path]
    first, rest = path.split('.', 1)
    return get_node(d[first], rest)

然后获得你想要的钥匙是微不足道的:

>>> old = {
  "a": "abc",
  "b": {"b1": "1", "b2": "2", "b3": "3"},
  "c": 1,
  "d": "timmy",
  "e": "John"
}
>>> {v: get_node(old, k) for k, v in mappings.iteritems()}
{'out_b2': '2', 'out_c': 1, 'out_d': 'timmy'}

我在最后一部分使用了词典理解 - 如果你的Python版本不支持,你可以使用以下代码:

dict((v, get_node(old, k)) for k, v in mappings.iteritems())