简体   繁体   English

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

[英]Search and update nested dictionary based on key name

I have a nested dictionary of a variable depth for which I want to update a key with a string if the key is already present in the dictionary and if the key is not present add the key to the root of the dictionary.我有一个可变深度的嵌套字典,如果键已经存在于字典中,并且如果键不存在,我想用字符串更新键,如果键不存在,则将键添加到字典的根。 For example, let's say the original dictionary is:例如,假设原始字典是:

 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' }
 }

Now, I want to update key_1_level_2 with the string new_item so that the dictionary looks like this:现在,我想用字符串new_item更新key_1_level_2以便字典看起来像这样:

 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'} 
 }

I can't use d.update({'key_1_level_2': 'new_item'}) because it won't work in lower levels besides the root.我不能使用d.update({'key_1_level_2': 'new_item'})因为它不能在除根之外的较低级别工作。 So doing it will end up in:所以这样做最终会变成:

     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'} 
     }

However, please note that if the input key is key_2_level_1 with a string value.但是,请注意,如果输入键是带有字符串值的key_2_level_1 It must overwrite the dictionary in that level with the input string value.必须用输入字符串值覆盖该级别的字典。

On the other hand, if the input does not exist, ie key_3_level_1 = new_item , it should be added to the root, like:另一方面,如果输入不存在,即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', 
 }

So far I tried this function.到目前为止,我尝试了这个功能。 It will only receive string values .它只会接收字符串值 This works for already present keys, but fails to create new keys:这适用于已经存在的密钥,但无法创建新密钥:

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'}

Ideally the output for this should have been:理想情况下,此输出应该是:

{'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'}

What would be the best way to do this?什么是最好的方法来做到这一点?

You need to make sure that we eventually add the key to the outer-most dictionary if we've never found it:如果我们从未找到它,您需要确保我们最终将键添加到最外层字典:

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'}

You will also note that I changed the interface of your function: Since it modifies the dictionary in-place, it shouldn't return it.您还会注意到我更改了函数的接口:由于它就地修改了字典,因此不应返回它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM