递归遍历带有列表的嵌套字典,并替换匹配的值

Posted

技术标签:

【中文标题】递归遍历带有列表的嵌套字典,并替换匹配的值【英文标题】:Recursively iterate through a nested dict with list, and replace matched values 【发布时间】:2019-09-06 21:26:21 【问题描述】:

我想创建一个函数来遍历包含列表的嵌套字典。对于每个与关键字匹配的值,该函数将其替换为另一个关键字。

函数是否返回另一个字典或是否更改主字典并不重要。

我试图将案例分开: - 如果数据是字典,做点什么 - 如果数据是一个列表,做别的东西

字典:


data_dict = 
  "name": "AAAAAA",
  "content": "BBBBBB",
  "dat": [
    
      "author": 
        "name": "CCCCCC",
        "surname": "DDDDDD",
      ,
      "title": "FFFFFF",
      "color": 15258703,
      "fields": [
        
          "name": "GGGGGG",
          "value": "HHHHHH",
        ,
        
          "name": "IIIIII",
          "value": "JJJJJJ",
        

      ],
      "thumbnail": 
        "url": "KKKKKK"
      ,
      "image": 
        "url": "LLLLLL"
      ,
      "footer": 
        "text": "MMMMMMM",
        "icon_url": "NNNNNN"
      
    
  ]



现在我只是尝试更改每个值,看看我是否也在迭代。 我可以打印所有更改值的data_dict,但我无法在字典中管理它...


def recursive_replace_valuer(data, match, repl):

    if isinstance(data, list):
        for l in data:
            recursive_replace_valuer(l, match, repl)
            if isinstance(l, dict):
                recursive_replace_valuer(l, match, repl)




    elif isinstance(data, dict):
        for k,v in data.items():
            recursive_replace_valuer(v, match, repl)
            data[k] = '______'
        print(data)

recursive_replace_valuer(data_dict, 'a','a')

【问题讨论】:

【参考方案1】:

函数应该递归地将函数应用于字典或列表中的值,直到输入data既不是字典也不是列表,此时如果给定的数据与给定的数据匹配,则返回替换值repl搜索字符串match:

def replace(data, match, repl):
    if isinstance(data, dict):
        return k: replace(v, match, repl) for k, v in data.items()
    elif isinstance(data, list):
        return [replace(i, match, repl) for i in data]
    else:
        return repl if data == match else data

或者,要就地替换原始数据,使函数遍历给定的字典或列表,如果匹配,则用键(对于字典)或索引(对于列表)替换一个值,然后递归地应用函数值:

def replace(data, match, repl):
    if isinstance(data, (dict, list)):
        for k, v in (data.items() if isinstance(data, dict) else enumerate(data)):
            if v == match:
                data[k] = repl
            replace(v, match, repl)

【讨论】:

如果值为set怎么办? @BasilMusa 加elif isinstance(data, set): return replace(i, match, repl) for i in data 迭代期间字典键发生变化 @AmulyaAcharya 您是在谈论错误“RuntimeError:迭代期间字典更改大小”吗?您能否提供可能导致此错误的示例输入数据集? data[k] = repl 所做的只是为现有键分配一个新值,所以我看不出它如何改变 dict 的大小以产生该错误。

以上是关于递归遍历带有列表的嵌套字典,并替换匹配的值的主要内容,如果未能解决你的问题,请参考以下文章

遍历字典列表并 1) 将流值与流列元素进行比较 2) 如果匹配,则附加一个带有数据的新列表

如何递归遍历 R 列表中的所有键值对并修改值? [复制]

递归遍历未知结构的NSDictionary

如何加快递归搜索功能?

带有字典、列表和 If 语句的嵌套循环

遍历嵌套字典以创建数据框并添加新的列值