首页 > 解决方案 > 如何导航包含数组的 JSON 文件以在 python 中使用 Objectpath 选择值?

问题描述

我有多个 JSON 文件要覆盖,但似乎无法访问下面的特定文本(干扰)。这是文件中一行的示例:

{"extracted":"high","nameid":3201932,"users":{"name":[{"ids":[28,37],"text":"distracter"}],"symbols":[]}}

下面是我编写的返回空结果的代码:

data = []
with open(fileName, 'r') as file_to_read:
    for line in file_to_read:
        data.append(json.loads(line))
        json_tree = objectpath.Tree(data)
        text_result= tuple(json_tree.execute('$.users.name[@.text]'))
return text_result

标签: pythonarraysjsontreeobjectpath

解决方案


我认为这里有两个主要问题:

  1. 选择器查询似乎错误 - 我已经尝试过'$.users.name.text',发现它对我有用(使用 Python3 和 objectpath)
  2. 该函数未正确建立名称列表

尝试这样的事情:

import json
import objectpath


def get_names_tree(data):
    tree = objectpath.Tree(data)
    return tuple(tree.execute('$.users.name.text'))


def load_data(file_name):
    names = []

    with open(file_name) as fh:
        for line in fh:
            data = json.loads(line)
            names.extend(get_names_tree(data))

    return names

在上面的循环中,我们建立了一个名称列表,而不是解码的实体。在您的版本中,text_result变量被重复实例化,并且只返回最后一个。

您还可以通过使用纯 Python 方法获取数据来提高速度。

def get_names_careful(data):
    return tuple(
        name['text'] for name in
        data.get('users', {}).get('name', [])
        if 'text' in name
    )


def get_names(data):
    return tuple(name['text'] for name in data['users']['name'])

第一个注意不要因缺少数据而引发错误,但如果您知道您的数据始终是正确的形状,您可以尝试第二个。

在我的测试中,它们的速度提高了 15 倍(谨慎的版本),而粗心的版本则快了 20 倍。


推荐阅读