RError.com

RError.com Logo RError.com Logo

RError.com Navigation

  • 主页

Mobile menu

Close
  • 主页
  • 系统&网络
    • 热门问题
    • 最新问题
    • 标签
  • Ubuntu
    • 热门问题
    • 最新问题
    • 标签
  • 帮助
主页 / 问题 / 1538666
Accepted
babyborn
babyborn
Asked:2023-09-01 21:23:40 +0000 UTC2023-09-01 21:23:40 +0000 UTC 2023-09-01 21:23:40 +0000 UTC

通过对象中的键检索所​​有 JSON 对象

  • 772

有一个非常大的 JSON,例如:

{
 'id': 'someid',
 'type': 'group',
 'children': [
    {
     'id': 'someid',
     'type': 'group',
     'children': [
        {
         'id': 'someid',
         'type': 'person'
        }
     ]
    }
 ]
}

我需要使用Python提取所有对象,一个完整的类型对象:

{
 'id': 'someid',
 'type': 'person'
}

如果在一个对象中type==person(那么我会将这些对象添加到列表中)。如果 JSON 非常大并且子对象的数量未知并且可能会发生变化,该怎么办?

python
  • 2 2 个回答
  • 50 Views

2 个回答

  • Voted
  1. Best Answer
    CrazyElf
    2023-09-01T21:41:56Z2023-09-01T21:41:56Z

    只需递归地遍历元素并收集您需要的元素即可:

    def find_data(d, type_):
        if isinstance(d, dict):
            if d['type'] == type_:
                yield {'id': d['id'], 'type': d['type']}
            if 'children' in d:
                yield from find_data(d['children'], type_)
        elif isinstance(d, list):
            for x in d:
                yield from find_data(x, type_)
        else:
            raise ValueError(); 
    
    data = {'id':'someid',
            'type':'group',
            'children':
                [{'id':'someid',
                'type':'group',
                'children':
                    [{'id':'someid',
                    'type':'person'}]}]}
    
    result = list(find_data(data, 'person'))
    print(result)
    

    结论:

    [{'id': 'someid', 'type': 'person'}]
    

    如果person最终元素肯定没有children,那么就简单一点;yield {'id': d['id'], 'type': d['type']}您可以返回整个当前字典,而不是包含某些元素的新字典yield d。

    • 2
  2. Tananndart
    2023-09-05T18:35:11Z2023-09-05T18:35:11Z

    使用 ijson 的解决方案,无需递归且无需将所有 json 加载到内存中。

    import ijson
    
    
    def extract_filtered_json_objects(path_to_json, filter_key, filter_value):
        """
        Последовательно считывает json файл, затем возвращает список отфильтрованных json объектов.
        :param path_to_json: путь до json файла;
        :param filter_key: ключ фильтрации;
        :param filter_value: необходимое значение ключа фильтрации;
        :return: список из отфильтрованных json объектов.
        """
        results = []
    
        with open(path_to_json, 'r') as file:
            parser = ijson.parse(file)
    
            # Последовательно читаем json файл
            # prefix - это путь до текущей ноды;
            # event - это тип ноды, например start_map это начало списка, end_map это конец списка и т.д.
            # value - это значение текущего элемента (может принимать различные типы: None, строка, int и т.д.)
            for prefix, event, value in parser:
                # тут нас интересуют элементы списков в json и событие по нахождению какого-либо ключа в этом списке
                if prefix.endswith('.item') and event == 'map_key':
                    # заготовка под объект json, который будем строить
                    json_object = {}
                    # пока в текущем списке есть элементы, будем их анализировать
                    while event == 'map_key':
                        # ijson идет итеративно по ключам и значениям
                        # поэтому сначала сохраняем уже полученный ключ,
                        # а потом запускаем следующую итерацию для получения значения
                        key = value
                        _, _, value = next(parser)
                        json_object[key] = value
                        # для продолжения нашего while нам нужно снова перейти на следующий ключ списка
                        # поэтому в этой итерации мы специально сеттим event (там как раз будет map_key)
                        prefix, event, value = next(parser)
    
                    # с построенным объектом json можем делать что угодно, тут мы сверяем его с фильтром и записываем
                    if filter_key in json_object and json_object[filter_key] == filter_value:
                        results.append(json_object)
    
        return results
    
    
    if __name__ == "__main__":
        json_file = "test3.json"
        
        persons = extract_filtered_json_objects(json_file, 'type', 'person')
        for person in persons:
            print(person)
    
    • 0

相关问题

  • 是否可以以某种方式自定义 QTabWidget?

  • telebot.anihelper.ApiException 错误

  • Python。检查一个数字是否是 3 的幂。输出 无

  • 解析多个响应

  • 交换两个数组的元素,以便它们的新内容也反转

Sidebar

Stats

  • 问题 10021
  • Answers 30001
  • 最佳答案 8000
  • 用户 6900
  • 常问
  • 回答
  • Marko Smith

    我看不懂措辞

    • 1 个回答
  • Marko Smith

    请求的模块“del”不提供名为“default”的导出

    • 3 个回答
  • Marko Smith

    "!+tab" 在 HTML 的 vs 代码中不起作用

    • 5 个回答
  • Marko Smith

    我正在尝试解决“猜词”的问题。Python

    • 2 个回答
  • Marko Smith

    可以使用哪些命令将当前指针移动到指定的提交而不更改工作目录中的文件?

    • 1 个回答
  • Marko Smith

    Python解析野莓

    • 1 个回答
  • Marko Smith

    问题:“警告:检查最新版本的 pip 时出错。”

    • 2 个回答
  • Marko Smith

    帮助编写一个用值填充变量的循环。解决这个问题

    • 2 个回答
  • Marko Smith

    尽管依赖数组为空,但在渲染上调用了 2 次 useEffect

    • 2 个回答
  • Marko Smith

    数据不通过 Telegram.WebApp.sendData 发送

    • 1 个回答
  • Martin Hope
    Alexandr_TT 2020年新年大赛! 2020-12-20 18:20:21 +0000 UTC
  • Martin Hope
    Alexandr_TT 圣诞树动画 2020-12-23 00:38:08 +0000 UTC
  • Martin Hope
    Air 究竟是什么标识了网站访问者? 2020-11-03 15:49:20 +0000 UTC
  • Martin Hope
    Qwertiy 号码显示 9223372036854775807 2020-07-11 18:16:49 +0000 UTC
  • Martin Hope
    user216109 如何为黑客设下陷阱,或充分击退攻击? 2020-05-10 02:22:52 +0000 UTC
  • Martin Hope
    Qwertiy 并变成3个无穷大 2020-11-06 07:15:57 +0000 UTC
  • Martin Hope
    koks_rs 什么是样板代码? 2020-10-27 15:43:19 +0000 UTC
  • Martin Hope
    Sirop4ik 向 git 提交发布的正确方法是什么? 2020-10-05 00:02:00 +0000 UTC
  • Martin Hope
    faoxis 为什么在这么多示例中函数都称为 foo? 2020-08-15 04:42:49 +0000 UTC
  • Martin Hope
    Pavel Mayorov 如何从事件或回调函数中返回值?或者至少等他们完成。 2020-08-11 16:49:28 +0000 UTC

热门标签

javascript python java php c# c++ html android jquery mysql

Explore

  • 主页
  • 问题
    • 热门问题
    • 最新问题
  • 标签
  • 帮助

Footer

RError.com

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

帮助

© 2023 RError.com All Rights Reserve   沪ICP备12040472号-5