如何从嵌套字典切片创建字典?

时间:2017-05-23 09:16:39

标签: python json dictionary

我有一本字典:

dictionary = {
    "key1" : 
        {
         "key11" : ["a", "b"],
         "key12" : "c"
        },
    "key2": "d",
    "key3": 
        {
         "key31" : ["e", "f"],
         "key32" : "g"
        }
}

我想创建另一个字典,第一个字典的部分。这样做的目的是使我的脚本用户能够将他想要从旧文件中提取的密钥传递给新文件。我希望新词典的形状如下:

dictionary_bis = {
    "key1" : 
        {
          "key11" : ["a", "b"]
        },
    "key3" : 
        {
          "key32": "g"
        }
}

我现在拥有的是:

dictionary_1 = {}
dictionary_1["key1"] = {}
dictionary_1["key1"]["key11"] = dictionary["key1"["key11"]
dictionary_1["key3"] = {}
dictionary_1["key3"]["key32"] = dictionary["key3"]["key32"]

这似乎是一种糟糕的方式,因为每次用户更改他想要提取的密钥时,我都需要再次对其进行硬编码。必须有一些更优雅的方法来做到这一点。

修改

为了澄清:我在mongodb的一个集合中有一个巨大的文档,我的软件用户希望能够创建一个新文档,其中包含来自第一个文档的一些数据并将其保存在另一个集合中。这就是我提出的。如果你愿意的话,它可以是从一个字典到另一个字典的一些元素的副本。

1 个答案:

答案 0 :(得分:1)

你可以用词典理解来做到这一点:

keys_to_keep = ("key1", "key3")
new_dict = {k:v for k, v in old_dict.items() if k in keys_to_keep}

如果您可以安全地假设密钥永不重复,并且只有2级嵌套,您可以尝试:

keys_to_keep = ("key1", "key12", "key3", "key32")
new_dict = {}


for k, v in dictionary.items():

    if k not in keys_to_keep:
        continue

    if isinstance(v, dict):
        d = {subk: subv for subk, subv in v.items() if subk in keys_to_keep}
        new_dict[k] = d
    else:
        new_dict[k] = v

注意:要处理副本而不是对原始字典的引用,可以通过调用dictionary = old_dict.copy()deep copying使用copy模块处理副本。

对于任意嵌套词典:

from copy import deepcopy

def prunedict(old_dict, keys_to_keep, copy=False):

    new_dict = {}

    if copy:
        old_dict = deepcopy(old_dict)

    for k, v in old_dict.items():

        if k not in keys_to_keep:
            continue

        if isinstance(v, dict):
            d = prunedict(v, keys_to_keep, copy=False)
            # if d == {}: continue  ## In case you don't want empty entries.
            new_dict[k] = d
        else:
            new_dict[k] = v

    return new_dict