通过嵌套json递归迭代python中的特定键

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/21028979/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-18 21:50:33  来源:igfitidea点击:

recursive iteration through nested json for specific key in python

pythonjsonrecursioniterationlist-comprehension

提问by adam

I'm trying to pull nested values from a json file. I want to print out each of the values for every "id" key. I think I'm close but can't figure out why the obj type changes from a dict to a list, and then why I'm unable to parse that list. Here is a link to the json I'm working with: http://hastebin.com/ratevimixa.tex

我正在尝试从 json 文件中提取嵌套值。我想打印出每个“id”键的每个值。我想我很接近但无法弄清楚为什么 obj 类型从 dict 更改为列表,然后为什么我无法解析该列表。这是我正在使用的 json 的链接:http: //hastebin.com/ratevimixa.tex

and here is my current code:

这是我当前的代码:

#!/usr/bin/env python
#-*- coding: utf-8 -*-

import json

json_data = open('JubJubProductions.json', 'r+')
jdata = json.loads(json_data.read().decode("utf-8"))

def recursion(dict):

    for key, value in dict.items():

        if type(value) == type(dict):
            if key != "paging":
                for key, value in value.items():
                    if isinstance (value,list):
                        print key
                        # place where I need to enter list comprehension?
                if type(value) == type(dict):
                    if key == "id":
                        print " id found " + value
                    if key != "id":
                        print key + " 1st level"
                if key == "id":
                    print key
        else:
            if key == "id":
                print "id found " + value       
if __name__ == '__main__':
    recursion(jdata)

-------------------------------------------------------------------------------------------update

-------------------------------------------------- -----------------------------------------更新

This is now what I'm working with and it'll return a single id value, but not all of them:

这就是我现在正在使用的,它将返回一个 id 值,但不是全部:

#!/usr/bin/env python
#-*- coding: utf-8 -*-

import json

json_data = open('jubjubProductions', 'r+')
jdata = json.loads(json_data.read().decode("utf-8"))

def id_generator(d):
    for k, v in d.items():
        if k == "id":
            yield v
        elif isinstance(v, dict):
            for id_val in id_generator(v):
                yield id_val

if __name__ == '__main__':
    for _ in id_generator(jdata):
        print (_)

采纳答案by Filip Malczak

def id_generator(dict_var):
    for k, v in dict_var.items():
        if k == "id":
            yield v
        elif isinstance(v, dict):
            for id_val in id_generator(v):
                yield id_val

This will create an iterator which will yield every value on any level under key "id". Example usage (printing all of those values):

这将创建一个迭代器,它将产生键“id”下任何级别的每个值。示例用法(打印所有这些值):

for _ in id_generator(some_json_dict):
    print(_)

回答by Bo Sunesen

The JSON might contain a list of objects, which needs to be searched:

JSON 可能包含需要搜索的对象列表:

Python 2.7 version:

Python 2.7 版本:

def item_generator(json_input, lookup_key):
    if isinstance(json_input, dict):
        for k, v in json_input.iteritems():
            if k == lookup_key:
                yield v
            else:
                for child_val in item_generator(v, lookup_key):
                    yield child_val
    elif isinstance(json_input, list):
        for item in json_input:
            for item_val in item_generator(item, lookup_key):
                yield item_val

Python 3.x version:

Python 3.x 版本:

def item_generator(json_input, lookup_key):
    if isinstance(json_input, dict):
        for k, v in json_input.items():
            if k == lookup_key:
                yield v
            else:
                yield from item_generator(v, lookup_key)
    elif isinstance(json_input, list):
        for item in json_input:
            yield from item_generator(item, lookup_key)