【问题标题】:Recursively find and return key and value from nested dictionaries python从嵌套字典python递归查找并返回键和值
【发布时间】:2021-12-16 13:58:55
【问题描述】:

有人可以帮我写下面的代码吗?

这最初是为了处理 json 文件中的数据,但我已将其转换为使用 json / 字典变量。

现在 get_data_value() 函数正在工作,但我想返回一个包含键和值的单数字典,而不是只返回值。

我只是不确定如何在不破坏递归的情况下转换 item_generator 函数以使其成为可能;我从 stackoverflow 上的示例中找到了这个函数。

def get_data_value(data,data_name):
    d = data['test']
    print(item_generator(d,data_name))
    for _ in item_generator(d,data_name):
        return (_)
    
def item_generator(json_input, lookup_key):
    if isinstance(json_input, dict):
        for key, value in json_input.items():
            if key == lookup_key:  
                data_single_item = {key:value}  # what i want to return
                print(data_single_item)       
                
                yield value                    # only value is returned
            else:
                yield from item_generator(value, lookup_key)
    elif isinstance(json_input, list):
        for item in json_input:
            yield from item_generator(item, lookup_key)
            

json_data = { "test": [ { "Tier1": [ { "Tier1-Main-Title-1": [ { "title": "main", "example": 400 } ] } ] }, { "Tier2": [] }, { "Tier3": [ { "Example1-Sub1": 44 } ] } ] }

print(get_data_value(json_data,'title'))

【问题讨论】:

  • 如果代码完全相同,最好删除外部链接,因为无论如何都不需要:-)
  • 另外,item_generator 函数的意义何在?意思是,我们需要使用它吗?
  • item_generator 确实是我用来获取值的主要函数,当我在此处的示例中找到它时,这就是它的名称。为了使用它,我创建了 get_data_value() 来设置基本数据并循环获取值。我认为在执行 value = item_generator(d,data_name) 之前我无法获得价值。

标签: python python-3.x dictionary recursion


【解决方案1】:

值得指出的是这里有一个错误:

for _ in item_generator(d,data_name):
    return (_)

这是一个需要注意的重要情况,因为这里的return 语句只返回一次。因此,此for 循环仅在第一次迭代时运行,并且仅返回第一个 yield 结果 - 即仅在 json_data 中第一次出现查找键。

您可以使用生成器(或可迭代)解包到 list 来修复它,如下所示:

def get_data_value(data, data_name):
    d = data['test']
    return [*item_generator(d, data_name)]


def item_generator(json_input, lookup_key):
    if isinstance(json_input, dict):
        if lookup_key in json_input:
            yield {lookup_key: json_input[lookup_key]}
        else:
            for v in json_input.values():
                yield from item_generator(v, lookup_key)

    elif isinstance(json_input, list):
        for item in json_input:
            yield from item_generator(item, lookup_key)


json_data = {"test": [{"Tier1": [{"Tier1-Main-Title-1": [{"title": "main", "example": 400}]}]}, {"Tier2": []},
                      {"Tier3": [{"Example1-Sub1": 44, "title": "TEST2"}]}]}

print(get_data_value(json_data, 'title'))

结果:

[{'title': 'main'}, {'title': 'TEST2'}]

或者,如果您根本不想致电get_data_value

print(*item_generator(json_data['test'], 'title'))

由于函数本质上是递归的,因此传递密钥 'test' 是可选的。

默认情况下,结果以单个空格分隔,但您可以通过将sep 参数传递给打印语句来控制分隔符。

{'title': 'main'} {'title': 'TEST2'}

【讨论】:

    【解决方案2】:

    我不确定我是否遗漏了什么,但你为什么不直接返回你想要的?比如这样:

    def get_data_value(data,data_name):
        d = data['test']
        print(item_generator(d,data_name))
        for _ in item_generator(d,data_name):
            return (_)
    
    def item_generator(json_input, lookup_key):
        if isinstance(json_input, dict):
            for key, value in json_input.items():
                if key == lookup_key:      
                    yield {key:value} 
                else:
                    yield from item_generator(value, lookup_key)
        elif isinstance(json_input, list):
            for item in json_input:
                yield from item_generator(item, lookup_key)
    
    
    json_data = { "test": [ { "Tier1": [ { "Tier1-Main-Title-1": [ { "title": "main", "example": 400 } ] } ] }, { "Tier2": [] }, { "Tier3": [ { "Example1-Sub1": 44 } ] } ] }
    
    print(get_data_value(json_data,'title'))
    

    【讨论】:

      猜你喜欢
      • 2022-01-15
      • 2014-05-18
      • 1970-01-01
      • 2019-02-15
      • 2021-04-10
      • 2022-01-13
      • 2022-07-05
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多