根据键名搜索和更新嵌套字典

时间:2020-08-25 09:36:34

标签: python python-3.x

我有一个深度可变的嵌套字典,如果该键已存在于字典中,并且如果不存在该键,则我想使用字符串更新该键,然后将其添加到字典的根目录中。例如,假设原始字典是:

 d= { 
 'key_1_level_1': 'item_1_level_1', 
 'key_2_level_1': {
    'key_1_level_2': 'item_1_level_2', 
    'key_2_level_2': 'item_2_level_2' }
 }

现在,我想用字符串key_1_level_2更新new_item,以使字典看起来像这样:

 d= { 
 'key_1_level_1': 'item_1_level_1', 
 'key_2_level_1': {
    'key_1_level_2': 'item_1_level_2', 
    'key_2_level_2': 'item_2_level_2'} 
 }

我不能使用d.update({'key_1_level_2': 'new_item'}),因为它除了根目录以外在较低的层次上也无法使用。因此,这样做最终会导致:

     d= { 
     'key_1_level_1': 'item_1_level_1', 
     'key_2_level_1': {
        'key_1_level_2': 'new_item', 
        'key_2_level_2': 'item_2_level_2'},
      {'key_1_level_2': 'new_item'} 
     }

但是,请注意,如果输入键是带有字符串值的key_2_level_1。它必须使用输入的字符串值必须覆盖该级别的字典。

另一方面,如果输入不存在,即key_3_level_1 = new_item,则应将其添加到根中,例如:

 d= { 
 'key_1_level_1': 'item_1_level_1', 
 'key_2_level_1': {
    'key_1_level_2': 'item_1_level_2', 
    'key_2_level_2': 'item_2_level_2'}
 'key_3_level_1': 'new_item', 
 }

到目前为止,我尝试了此功能。 它将仅接收字符串值。 这适用于已经存在的密钥,但是无法创建新密钥:

d= { 'key_1_level_1': 'item_1_level_1', 
     'key_2_level_1': {
        'key_1_level_2': 'item_1_level_2', 
        'key_2_level_2': 'item_2_level_2'} 
     }

input_key = "new_key"
value = "new_item"

def _update_dictionary(dictionary, input_key, value):
  if input_key in dictionary:
    dictionary.update({input_key: value})
  else:
    for k, v in dictionary.items():
      if isinstance(v, dict):
        _update_dictionary(v, input_key, value)
  return  dictionary
  
dictionary = _update_dictionary(d, input_key, value)
print(dictionary)
{'key_2_level_1': {'key_2_level_2': 'item_2_level_2', 'key_1_level_2': 'item_1_level_2'}, 
'key_1_level_1': 'item_1_level_1'}

理想情况下,此输出应为:

{'key_2_level_1': {'key_2_level_2': 'item_2_level_2', 'key_1_level_2': 'item_1_level_2'}, 
'key_1_level_1': 'item_1_level_1',
'new_key': 'new_item'}

什么是最好的方法?

1 个答案:

答案 0 :(得分:0)

如果我们从未找到过密钥,则需要确保最终将其添加到最外层字典中:

def _update_dictionary(dictionary, key, value, root=True):
    success = False
    if key in dictionary:
        dictionary[key] = value
        return True
    for k, v in dictionary.items():
        if isinstance(v, dict):
            success = _update_dictionary(v, key, value, root=False)
            if success:
                return True
    if root and not success:
        dictionary[key] = value
        return True
    return False

>>> _update_dictionary(d, input_key, value)
>>> print(d)
{'key_1_level_1': 'item_1_level_1',
 'key_2_level_1': {'key_1_level_2': 'item_1_level_2',
  'key_2_level_2': 'item_2_level_2'},
 'new_key': 'new_item'}

您还将注意到,我更改了函数的接口:由于它就地修改了字典,因此不应返回它。