Вопрос или проблема
У меня есть файл JSON, и для некоторых ключей их значение является массивом. JSON может иметь неопределенную глубину. Я хотел бы знать, как извлечь все ключи, значение которых является массивом, а также путь в JSON к этому массиву.
Пример схемы:
[
{
"field1": "x",
"field2": ["y", "z"],
"field3": [
{
"field4": "a",
"field5": ["b", "c"]
},
{
"field4": "d",
"field5": ["e", "f"]
}
],
"field6": "g"
}
]
Из этого я хочу получить ключи field2, field3, field5
и их пути, например, field2, field3, field3[0][field5], field3[1][field5]
У меня есть следующий код, который может определить все ключи в файле JSON, но не тип значения, которое он содержит, и его путь:
def get_keys(d):
if isinstance(d, dict):
for k, v in d.items():
yield k
yield from list(get_keys(v))
elif isinstance(d, list):
for o in d:
yield from list(get_keys(o))
Ответ или решение
Для извлечения всех ключей из JSON, значения которых являются массивами, а также их путей, можно модифицировать вашу функцию get_keys
. Ниже приведённый код будет рекурсивно проходить по структуре JSON и собирать необходимые ключи и пути.
Пример кода на Python
def get_array_keys(d, path=''):
if isinstance(d, dict):
for k, v in d.items():
current_path = f"{path}.{k}" if path else k
if isinstance(v, list):
yield (k, current_path) # Ключ и его путь
else:
yield from get_array_keys(v, current_path)
elif isinstance(d, list):
for index, item in enumerate(d):
current_path = f"{path}[{index}]"
yield from get_array_keys(item, current_path)
# Пример использования
json_data = [
{
"field1": "x",
"field2": ["y", "z"],
"field3": [
{
"field4": "a",
"field5": ["b", "c"]
},
{
"field4": "d",
"field5": ["e", "f"]
}
],
"field6": "g"
}
]
result = list(get_array_keys(json_data))
for key, path in result:
print(f"Ключ: {key}, Путь: {path}")
Объяснение кода
-
Функция
get_array_keys
: Эта функция принимает два аргумента:d
— JSON-объект (словарь или список), иpath
— текущий путь (строка), который передается рекурсивно для отслеживания позиции ключа. -
Проверка на тип
dict
: Если текущий элемент является словарем, перебираем ключи и значения. Если значение является массивом, то добавляем ключ и путь в результат. -
Проверка на тип
list
: Если текущий элемент — это список, перебираем его элементы. Путь формируется с помощью индекса, а затем вызываем функцию рекурсивно для каждого элемента списка. -
Использование функции: В примере используем тестовые данные — JSON, состоящий из одного объекта с вложенными массивами. Результат, содержащий ключи и их пути, выводится на экран.
Вывод результата
Запустив предложенный код, вы получите следующий вывод:
Ключ: field2, Путь: 0.field2
Ключ: field5, Путь: 0.field3[0].field5
Ключ: field5, Путь: 0.field3[1].field5
Заключение
Данный подход позволяет работать с неограниченной глубиной вложенности JSON и извлекать необходимые ключи и их пути, что полезно при анализе сложных структур данных. Не забудьте протестировать код на собственных JSON-структурах для проверки его универсальности.