Как я могу перемещаться по файлу JSON с массивом для выбора значений с помощью Objectpath в python? - PullRequest
0 голосов
/ 21 сентября 2018

У меня есть несколько файлов 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

1 Ответ

0 голосов
/ 21 сентября 2018

Я думаю, что здесь есть две основные проблемы:

  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 раз быстрее для небрежной версии.

...