根据一个字典的结构(框架)和另一个字典相应的值,创建一个嵌套字典。

3
假设我有一个名为 dict1 的字典,它具有我想要的新字典的结构(顺序和嵌套深度)。例如:
dict1 = {
   "Personnel": {
      "Performance": ""
   },
   "Gaming": {
      "Status": "",
      "Bug Status": ""
   },
   "Compatible": {
      "Minimum": "",
      "Integrity": "",
      "Scaling": ""
   },
   "Comparison": {
      "Difference": {
         "DirectX": ""
      },
      "Vendor": {
         "Intel": "",
         "Xiaomi": ""
      }
   }
}

我有另一个字典dict2,其中包含与上述dict1中键对应的值,以及其他一些键值对:

dict2 = {
   "Personnel": {
      "Performance": "10.5",
      "Maximum": "50.5"
   },
   "Gaming": {
      "Status": "Cool",
      "Bug Status": "None",
      "Green Status": "Black"
   },
   "Compatible": {
      "Minimum": "5",
      "Integrity": "Yes",
      "Scaling": "No"
   },
   "Comparison": {
      "Difference": {
         "DirectX": "50",
         "Android": "70"
      },
      "Vendor": {
         "Xiaomi": "40"
      }
   },
   "Another property": {
      "Testinfo": "TestTest",
      "Important": {
         "Wow": "MuchDoge"
      }
   }
}

我想创建一个新的字典,它的框架来自于dict1,键的相应值从dict2中获取。
注意:我希望跳过不属于dict1部分的键值对。例如:在我的新字典中,我不需要 'Green Status': 'Black'
以下是我尝试的代码:
def update(dict1 : dict, dict2: dict):  
    new_data = {}
    for k, v in dict1.items():
        if isinstance(v, dict):
            v = update(v, dict(dict2.keys()))
        if v not in dict2.keys():
            new_data[k] = v
    return new_data

但我完全没有理解其中的某些内容。
2个回答

3

您可以使用嵌套字典推导式来实现此操作。迭代dict1.items()以获取(key, value)元组对。再次迭代前一操作的value字典以获取嵌套新字典所需的键。然后,从dict2中获取相应键的值。例如:

new_dict = {k: {v_k: dict2[k][v_k] for v_k in v_dict} for k, v_dict in dict1.items() }

最好使用 dict.get('some_key') 来处理如果 some_key 键不存在时的异常。因此,上述字典解析表达式将变为:

new_dict = {k: {v_k: dict2.get(k, {}).get(v_k) for v_k in v_dict} for k, v_dict in dict1.items() }

如果dict1中的任何一个键在dict2中不存在,那么它将把None作为值存储。

对于您的示例数据,上述代码将返回new_dict

{
   "Compatible": {
      "Scaling": "No",
      "Minimum": "5",
      "Integrity": "Yes"
   },
   "Personnel": {
      "Performance": "10.5"
   },
   "Gaming": {
      "Status": "Cool",
      "Bug Status": "None"
   },
   "Comparison": {
      "Difference": {
         "Android": "70",
         "DirectX": "50"
      },
      "Vendor": {
         "Xiaomi": "40"
      }
   }
}

1
您可以在编程中使用 zip 递归:
from pprint import pprint
dict1 = {'Personnel':
     {'Performance': ''},
 'Gaming':
     {'Status': '',
      'Bug Status': ''},
 'Compatible':
     {'Minimum': '',
      'Integrity': '',
      'Scaling': ''},
 'Comparison':
     {'Difference':
          {'DirectX': ''},
      'Vendor':
          {'Intel': '',
           'Xiaomi': ''}
      }
 }

dict2 = {'Personnel':
         {'Performance': '10.5',
          'Maximum': '50.5'},
     'Gaming':
         {'Status': 'Cool',
          'Bug Status': 'None',
          'Green Status': 'Black',
          },
     'Compatible':
         {'Minimum': '5',
          'Integrity': 'Yes',
          'Scaling': 'No'},
     'Comparison':
         {'Difference':
              {'DirectX': '50',
               'Android': '70'},
          'Vendor':
              { 'Xiaomi': '40'}

          },
     'Another property':
         {
             'Testinfo': 'TestTest',
             'Important': {
                 'Wow': 'MuchDoge'
             }
         }
     }

def update(h, j):
   return {a:d if (a == c and not isinstance(b, dict)) or not isinstance(b, dict) or not isinstance(d, dict) else update(b.items(), d.items()) for (a, b), (c, d) in zip(h, j)}

pprint(update(dict1.items(), dict2.items()))

输出:

{'Comparison': {'Difference': 'TestTest', 'Vendor': {'Intel': 
'MuchDoge'}},
'Compatible': {'Integrity': 'Yes', 'Minimum': '5', 'Scaling': 'No'},
'Gaming': {'Bug Status': {'Xiaomi': '40'},
           'Status': {'Android': '70', 'DirectX': '50'}},
'Personnel': {'Performance': '10.5'}}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接