【问题标题】:Is there a way to keep indexing nested dictionaries until you find a string value?有没有办法保持索引嵌套字典直到找到字符串值?
【发布时间】:2019-11-13 15:40:42
【问题描述】:

我正在使用字典。它有一些嵌套的字典。它看起来像这样:

如您所见,educationexperience 具有嵌套的字典。 skillsindustrysummary 只是带​​有值的键。

{
  "education": [
    {
      "start": "1991",
      "major": "Human Resources"
    },
    {
      "start": "1984",
      "major": "Chemistry"
    }
  ],
  "skills": [
    "AML",
    "Relationship Management",
    "Team Management"
  ],
  "industry": "Banking",
  "experience": [
    {
      "org": "Standard Chartered Bank",
      "desc": "text"
    },
    {
      "org": "Tesa Tapes India Pvt. Ltd.",
      "desc": "text",
      "start": "October 1993",
      "title": "Product Manager/Application Engineer"
    }
  ],
  "summary": "text blah blah blah"
}

我需要访问与键startmajor对应的所有值,以及来自skillsindustryorgdescsummary的字符串列表,这样我就可以修改字符串。

那么有没有办法像这样访问这些值:

for keys in outerDict.keys():
    if outerDict[keys] has a nested dict:
        for keys in nestedDict.keys():
            nestedDict[keys] = doStuffToString(nestedDict[keys])
    else:
        outerDict[keys] = doStuffToString(outerDict[keys])

换句话说,继续索引嵌套的字典(如果它们存在的话),直到你找到一个字符串值。

一个更好的答案可能会处理一般情况:嵌套在其他字典中的可变数量的字典。也许有嵌套的 dicts 深入了几层(dicts inside of dicts inside of dicts inside of dicts...直到最终你遇到一些字符串/整数)。

【问题讨论】:

    标签: python dictionary indexing


    【解决方案1】:

    您可以使用递归函数。

    此函数将遍历字典,当它遇到一个列表时,它将遍历该列表中的每个字典,直到找到您要查找的任何键。然后将该条目的值更改为 new_text:

        def change_all_key_text(input_dict, targ_key, new_text):
            for key, val in input_dict.items():
                if key == targ_key:
                    input_dict[key] = new_text
                elif isinstance(val, list):
                    for new_dict in val:
                        if isinstance(new_dict, dict):
                            change_all_key_text(new_dict, targ_key, new_text)
    

    根据您的评论,如果您想更改每个字符串,而不考虑键(不包括键本身):

    def modify_all_strings(input_iterable, new_text):
        if isinstance(input_iterable, dict):
            for key, val in input_iterable.items():
                if isinstance(val, dict) or isinstance(val, list):
                    modify_all_strings(val, new_text)
                else:
                    # make changes to string here
                    input_iterable[key] = new_text
        elif isinstance(input_iterable, list):
            for idx, item in enumerate(input_iterable):
                if isinstance(item, dict) or isinstance(item, list):
                    modify_all_strings(item, new_text)
                else:
                    # make changes to string here
                    input_iterable[idx] = new_text
    

    在这里,您可以通过向 dict 添加一些结构来受益。由于主 dict 中每个键的值可以是 dicts 列表、字符串或字符串列表,因此您必须考虑许多输入情况。我不确定你是否已经了解了典型的tree data structures,但在这里创建一个节点类并确保每个部分都是一个节点可能会有所帮助。

    【讨论】:

    • 我认为递归方法可能很好。如果您没有targ_key 怎么办?例如,您想要找到任何和所有字符串,并修改这些字符串,它属于什么键并不重要。或者换个角度看:想象这个系统就像一棵树,弦就是叶子。你想找到所有的叶子,并对这些叶子做点什么(所有的叶子都是一样的),但你不在乎你是怎么到达那里的,因此你没有target leaf
    • @HumptyDumpty 我已经更新了我的解决方案以包括这个案例。
    最近更新 更多