任何嵌套键都匹配的Python嵌套字典更新值

时间:2019-11-15 22:28:19

标签: python python-3.x

我有一个嵌套的字典,其中每个元素可以是任何类型,包括列表或 字典。 我正在寻找一种使用特定值更新任何深度的任何键的方法。 (因此,如果目标值不是列表或字典,则会进行替换)

例如

{
   'a': 1,
   'b': 2,
   'c': [{'a': 2, 'b': 3}],
   'd': [{'d_d': {'a': 1, 'b': 2}}],
   'e': {'a': 4},
}

将成为

{
   'a': 'xx',
   'b': 2,
   'c': [{'a': 'xx', 'b': 3}],
   'd': [{'d_d': {'a': 'xx', 'b': 2}}],
   'e': {'a': 'xx'},
}

该函数采用字典,键和新值之类的

update_nested(dict, key='a', value='xx')

3 个答案:

答案 0 :(得分:1)

让我们看看您需要哪些部分以及如何实现它们:

浏览字典

有三种不同的方法可以帮助您遍历字典:

dict.keys()

反复检查字典中的所有键。例如

for key in {"Hello": 10, "World", 20}.keys():
   print(k)
# output: Hello\nWorld

dict.items()

在字典中迭代所有(key, value)元组。 for k, v in d.items()

dict.values()

对字典中的所有值进行迭代。 for v in d.values()

处理嵌套字典

当您使用嵌套结构时,一个好的概念会recursion

简而言之:您可以使用不同的参数本身调用相同的函数。

将两个概念放在一起。

  • 遍历数组
  • 如果键与您要搜索的键相同:请替换值
  • 如果值是dict:以值作为dict参数再次调用函数
  • 如果值是列表:遍历所有项目并检查它们是否为字典。如果是这样,请像上面一样处理它们

可能的最终代码:

def update_nested(in_dict, key, value):
   for k, v in in_dict.items():
       if key == k:
           in_dict[k] = value
       elif isinstance(v, dict):
           update_nested(v, key, value)
       elif isinstance(v, list):
           for o in v:
               if isinstance(o, dict):
                   update_nested(o, key, value)

额外说明:

永远不要使用内置名称/类型作为变量名称。就您而言,dict。这将覆盖内置类型,并可能导致意外行为。

答案 1 :(得分:0)

您可以使用递归函数来检查dictlist的实例:

def nested_update(obj, key, value):
    if isinstance(obj, dict):
        for k, v in obj.items():
            if isinstance(v, (dict, list)):
                nested_update(v, key, value)
            elif k == key:
                obj[k] = value
    elif isinstance(obj, list):
        for item in obj:
            nested_update(item, key, value)

答案 2 :(得分:0)

我在更新不同嵌套字典中导入的 JSON 值时遇到了类似的问题。

使用@Uli Sotschok 的解决方案,这是我的工作代码:

def changejsonimage(key, value, dictionary):
    for k,v in dictionary.items():
        if isinstance(v, str) and 'images' in v: #if string and has 'images' in the value
            dictionary[k] = 'InlineImage(tpl,"' + v + '")' #change the value
        elif isinstance(v, dict): #any value that is a dictionary, loop back into the fn
            changejsonimage(key,value,v)