有没有一种方法可以完全遍历长度不可预测但结构可预测的python字典?

有没有一种方法可以完全遍历长度不可预测但结构可预测的python字典?,python,Python,考虑以下词典: { "Key1":"value1", "Key2": [] } 访问Key1的值很简单:dict_name['Key1']。现在再考虑一下: { "Key1":"valueA", "Key2": [ { "Key1":"valueB",

考虑以下词典:

{
    "Key1":"value1",
    "Key2": []
}
访问Key1的值很简单:
dict_name['Key1']
。现在再考虑一下:

{
    "Key1":"valueA",
    "Key2": [
        {
            "Key1":"valueB",
            "Key2":[]
        },
        {
            "Key1":"valueC",
            "Key2":[]
        }
    ]
}
我的目标是获得所有Key1值的列表。因此,对于这本词典,我可以这样做:

values_list = [dictionary_name['Key1']]
additional_values = [child['Key1'] for child in dictionary_name['Key2']]
values_list.extend(additional_values)
print(values_list)

Out: ['valueA', 'valueB', 'valueC']
现在考虑一下,如果你不知道KEY2可能有多少后代。但您知道,任何/所有节点的格式都相同:

{
    "Key1":"value1",
    "Key2": [some or none child nodes]
}
所以我的问题是:有没有办法建立一个所有可能的Key1值的列表?

我目前混乱的尝试只能让我达到第二个层次

values_list = []
for first_level in first_levels:
    values_list.append(first_level['Key1'])
    next_levels = first_level.get('Key2', [])
    next_levels_len = len(next_levels)
    while next_levels_len > 0:
        next_levels_len = 0
        for next_level in next_levels:
            values_list.append(next_level['Key1'])
            next_levels = next_level.get('Key2', [])
            next_levels_len += len(next_levels)

以下是一个简单的版本:

def get_key1(d):
    vals = [d['Key1']]
    for subd in d['Key2']:
        vals += get_key1(subd)
    return vals
然后通过执行
get\u key1(my\u dict)
来使用它


其思想是,您希望将逻辑放入一个函数中,并让该函数为每个嵌套字典调用自己,然后将返回的值添加到列表中。

以下是一个简单的版本:

def get_key1(d):
    vals = [d['Key1']]
    for subd in d['Key2']:
        vals += get_key1(subd)
    return vals
然后通过执行
get\u key1(my\u dict)
来使用它


其思想是,您希望将逻辑放入一个函数中,并让该函数为每个嵌套字典调用自己,然后将返回的值添加到列表中。

给出了一个很好的逻辑答案,但为了简单起见,您可以使用
Regex Expression
提取出这样的模式。在使用此方法之前,请查看dict对象的
字符串表示形式
。例如:

>>>d = {"key1":"valueA"}
>>>str(d)
{'key1': 'valueA'}
所以这里有几点需要注意:
1.双引号(“)替换为单引号(”)。
2.冒号后空格。
基本上,这些都是python中使用的编码约定,但我们在编码时忽略了它们

dictionary_name ={
    "Key1":"valueA",
    "Key2": [
        {
            "Key1":"valueB",
            "Key2":[]
        },
        {
            "Key1":"valueC",
            "Key2":[]
        }
    ]
}

str_ = str(dictionary_name)
import re
regobt = re.compile(r"'Key1': '\w*'")
list_ = regobt.findall(str_)
print(list_)
输出:

["'Key1': 'valueA'", "'Key1': 'valueB'", "'Key1': 'valueC'"]
['Key1 valueA', 'Key1 valueB', 'Key1 valueC']
从输出中提取数据: 通过各种方法从这里提取您的需求,比如再次使用“正则表达式”或“字符串索引”。 不要使用这个额外的代码
。替换(“,”)。替换(“:”,“)
str
并使用此
re.compile(r“Key1\w*”)
更新您的正则表达式对象

现在输出为:

["'Key1': 'valueA'", "'Key1': 'valueB'", "'Key1': 'valueC'"]
['Key1 valueA', 'Key1 valueB', 'Key1 valueC']

下面给出了一个很好的逻辑答案,但为了简单起见,您可以使用
Regex Expression
提取出这样的模式。在使用此模式之前,请查看dict对象的
字符串表示形式。例如:

>>>d = {"key1":"valueA"}
>>>str(d)
{'key1': 'valueA'}
所以这里有几点需要注意:
1.双引号(“)替换为单引号(”)。
2.冒号后空格。
基本上,这些都是python中使用的编码约定,但我们在编码时忽略了它们

dictionary_name ={
    "Key1":"valueA",
    "Key2": [
        {
            "Key1":"valueB",
            "Key2":[]
        },
        {
            "Key1":"valueC",
            "Key2":[]
        }
    ]
}

str_ = str(dictionary_name)
import re
regobt = re.compile(r"'Key1': '\w*'")
list_ = regobt.findall(str_)
print(list_)
输出:

["'Key1': 'valueA'", "'Key1': 'valueB'", "'Key1': 'valueC'"]
['Key1 valueA', 'Key1 valueB', 'Key1 valueC']
从输出中提取数据: 通过各种方法从这里提取您的需求,比如再次使用“正则表达式”或“字符串索引”。 不要使用这个额外的代码
。替换(“,”)。替换(“:”,“)
str
并使用此
re.compile(r“Key1\w*”)
更新您的正则表达式对象

现在输出为:

["'Key1': 'valueA'", "'Key1': 'valueB'", "'Key1': 'valueC'"]
['Key1 valueA', 'Key1 valueB', 'Key1 valueC']

你可能想写一个递归函数。你可能想写一个递归函数。我真的很喜欢这种方法,但它并不是一种真正可靠的方法。它假定Key1值由所有单词字符组成。它还假设键和值由单引号分隔,这是不保证的,并且(在当前Python中)如果它们本身包含任何单引号,则不会为真。当然,即使是原始问题上的微小变化,也很难一概而论,例如,如果值可以是元组而不是列表,或者键2可能丢失或只有一个字符串值,等等。使用字典结构比依赖“stringly type”要好数据。@BrenBarn我100%同意您的稳健性观点,但我们可以使用
eval
来评估该值所属的数据类型。这就是python,一切皆有可能:)我真的很喜欢这种方法,但它并不是一种真正健壮的方法。它假定Key1值由所有单词字符组成。它还假设键和值由单引号分隔,这是不保证的,并且(在当前Python中)如果它们本身包含任何单引号,则不会为真。当然,即使是原始问题上的微小变化,也很难一概而论,例如,如果值可以是元组而不是列表,或者键2可能丢失或只有一个字符串值,等等。使用字典结构比依赖“stringly type”要好数据。@BrenBarn我100%同意您的稳健性观点,但我们可以使用
eval
来评估该值所属的数据类型。这是python,一切皆有可能:)