Рекурсивно найти путь и местоположение значения в списке

Я работаю над синтаксическим анализом огромных вложенных файлов JSON (иногда размер файла превышает 25 МБ) с использованием библиотека для PythonESPRIMA. У меня проблема с поиском местоположения значений в списках в файле JSON.

Вот небольшой упрощенный пример файла JSON:

parsed = {
    "type": "Program",
    "body": [
        {
        },
        {
            "type": "ExpressionStatement",
            "expression": {
                "type": "CallExpression",
                "callee": {
                    "type": "MemberExpression",
                    "computed": "false",
                    "object": {
                        "type": "Identifier",
                        "name": "localStorage"
                    },
                    "property": [
                        {
                            "a": [
                                {
                                    "type": "Identifier"
                                },
                                {
                                    "name": "getItem",
                                    "property": [
                                        {
                                            "b": [
                                                {
                                                    "name": "getItem"
                                                },
                                                {
                                                    "name": "getItem"
                                                }
                                            ]
                                        }
                                    ]
                                }
                            ]
                        },
                        {
                            "type": "Identifier",
                            "name": "getItem"
                        },
                        {
                            "type": "Identifier"
                        },
                        {
                            "type": "Identifier",
                            "name": "abcd"
                        },
                        {
                            "type": "Identifier",
                            "name": "getItem"
                        }
                    ]
                },
                "arguments": [
                    {
                        "type": "Literal",
                        "value": "myCat0",
                        "raw": "'myCat0'"
                    }
                ]
            }
        },
    ],
    "sourceType": "script"
}

Я использую следующую функцию:

result_k = []
path_k = []
x = z = 0

def get_keys(dic, target):
    global x, z
    try:
        if isinstance(dic, list) and dic:
            for d in dic:
                get_keys(d, target)
                z += 1
        else:
            for key, value in dic.items():
                path_k.append(key)
                if isinstance(value, list) and not value:
                    pass
                elif isinstance(value, list) and value:
                    for v in value:
                        path_k.append(x)
                        get_keys(v, target)
                        x += 1
                        path_k.pop()
                    x = 0
                elif isinstance(value, dict):
                    get_keys(value, target)
                if value == target:
                    result_k.append(z)
                    result_k.append(copy(path_k))
                path_k.pop()
    except Exception as err:
        print('\x1b[1;37;41m{}\x1b[0m'.format(str(err)))
        traceback.print_exc()

и вот результат, который неверен, когда дело доходит до списка после первого уровня; оба неверных местоположения выделяются в результате (после б):

[
1, ['expression', 'callee', 'property', 0, 'a', 1, 'property', 1, 'b', **1**, 'name'], 
1, ['expression', 'callee', 'property', 0, 'a', 1, 'property', 1, 'b', **2**, 'name'], 
1, ['expression', 'callee', 'property', 0, 'a', 1, 'name'], 
1, ['expression', 'callee', 'property', 1, 'name'], 
1, ['expression', 'callee', 'property', 4, 'name']
]

ОБНОВЛЕНИЕ 1: а ожидаемый результат следующий.

[
1, ['expression', 'callee', 'property', 0, 'a', 1, 'property', 1, 'b', **0**, 'name'], 
1, ['expression', 'callee', 'property', 0, 'a', 1, 'property', 1, 'b', **1**, 'name'], 
1, ['expression', 'callee', 'property', 0, 'a', 1, 'name'], 
1, ['expression', 'callee', 'property', 1, 'name'], 
1, ['expression', 'callee', 'property', 4, 'name']
]

Думаю, проблема возникает из-за повторения проверки, является ли список dict или list в строках if isinstance(dic, list): и dic и elif isinstance(value, list) and value:.

Каков ваш ожидаемый результат?

Mohit Motwani 10.08.2018 11:48

@MohitMotwani [1, ['выражение', 'вызываемый', 'свойство', 0, 'a', 1, 'свойство', 1, 'b', 0, 'имя'], 1, ['выражение', 'вызываемый', 'свойство', 0, 'a', 1, 'свойство', 1, 'b', 1, 'имя'], 1, ['выражение', 'вызываемый', 'свойство', 0, 'a', 1, 'name'], 1, ['выражение', 'вызываемый', 'свойство', 1, 'имя'], 1, ['выражение', 'вызываемый', 'свойство', 4, 'название'] ]

Alin 10.08.2018 13:23

Разместите это в своем вопросе, слишком непонятном, чтобы читать в комментариях.

Mohit Motwani 10.08.2018 13:24

@MohitMotwani готово. Спасибо, что упомянули об этом.

Alin 10.08.2018 13:28

что такое 1, 0, 4 и 4 в вашем выводе?

Mohit Motwani 10.08.2018 13:34

Они занимают их позицию в списке. Например, когда вы попадаете в массив, вам нужно знать его положение, чтобы иметь возможность использовать его в будущем. Я добавил в массив позицию следующего шага своего ответа. теперь ['выражение', 'вызываемый', 'свойство', 1, 'имя'] означает, что для достижения «getItem» вам необходимо пройти по этому пути: parsed ['body'] [0] ['выражение'] [ 'callee'] ['свойство'] [1] ['na‌ me']

Alin 10.08.2018 13:38

Позвольте нам продолжить обсуждение в чате.

Alin 10.08.2018 13:51
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
0
7
43
0

Другие вопросы по теме