如何使用 python 中的 Objectpath 将其中包含数组的 JSON 文件导航到 select 值?
How can I navigate a JSON file that has an array in it to select the values using Objectpath in python?
我有多个 JSON 文件要覆盖,但似乎无法访问下面的特定文本(干扰项)。这是文件中一行的示例:
{"extracted":"high","nameid":3201932,"users":{"name":[{"ids":[28,37],"text":"distracter"}],"symbols":[]}}
下面是我写的 returns 一个空结果的代码:
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
我认为这里主要有两个问题:
- 选择器查询似乎有误 - 我已经用
'$.users.name.text'
试过了,发现对我有用(使用 Python3 和对象路径)
- 该函数未正确构建名称列表
试试这样的方法:
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 倍。
我有多个 JSON 文件要覆盖,但似乎无法访问下面的特定文本(干扰项)。这是文件中一行的示例:
{"extracted":"high","nameid":3201932,"users":{"name":[{"ids":[28,37],"text":"distracter"}],"symbols":[]}}
下面是我写的 returns 一个空结果的代码:
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
我认为这里主要有两个问题:
- 选择器查询似乎有误 - 我已经用
'$.users.name.text'
试过了,发现对我有用(使用 Python3 和对象路径) - 该函数未正确构建名称列表
试试这样的方法:
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 倍。