Я работаю над синтаксическим анализом огромных вложенных файлов 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:
.
@MohitMotwani [1, ['выражение', 'вызываемый', 'свойство', 0, 'a', 1, 'свойство', 1, 'b', 0, 'имя'], 1, ['выражение', 'вызываемый', 'свойство', 0, 'a', 1, 'свойство', 1, 'b', 1, 'имя'], 1, ['выражение', 'вызываемый', 'свойство', 0, 'a', 1, 'name'], 1, ['выражение', 'вызываемый', 'свойство', 1, 'имя'], 1, ['выражение', 'вызываемый', 'свойство', 4, 'название'] ]
Разместите это в своем вопросе, слишком непонятном, чтобы читать в комментариях.
@MohitMotwani готово. Спасибо, что упомянули об этом.
что такое 1, 0, 4 и 4 в вашем выводе?
Они занимают их позицию в списке. Например, когда вы попадаете в массив, вам нужно знать его положение, чтобы иметь возможность использовать его в будущем. Я добавил в массив позицию следующего шага своего ответа. теперь ['выражение', 'вызываемый', 'свойство', 1, 'имя'] означает, что для достижения «getItem» вам необходимо пройти по этому пути: parsed ['body'] [0] ['выражение'] [ 'callee'] ['свойство'] [1] ['na me']
Позвольте нам продолжить обсуждение в чате.
Каков ваш ожидаемый результат?