Сжатие ключей во вложенных словарях Python: плоское представление

Пройдите тест, узнайте какой профессии подходите

Я предпочитаю
0%
Работать самостоятельно и не зависеть от других
Работать в команде и рассчитывать на помощь коллег
Организовывать и контролировать процесс работы

Быстрый ответ

Преобразование вложенных словарей можно осуществить с использованием рекурсивной функции, которая объединяет ключи разных уровней вложенности вместе. Для этого можно использовать параметр sep, которому можно задать значение разделителя, например, нижнее подчеркивание. Пример на языке Python:

Python
Скопировать код
def flatten_dict(d, parent_key=''):
    flat_dict = {}
    for k, v in d.items():
        new_key = f"{parent_key}{k}_" if parent_key else k
        if isinstance(v, dict):
            flat_dict.update(flatten_dict(v, new_key))
        else:
            flat_dict[new_key[:-1]] = v
    return flat_dict

print(flatten_dict({'a': {'b': {'c': 1}}}))  # Вывод: {'a_b_c': 1}

Функция flatten_dict преобразует словарь, имеющий несколько уровней вложенности, в словарь с одним уровнем. При этом каждый ключ содержит в себе полный путь, подобно профессиональной обработке данных.

Кинга Идем в IT: пошаговый план для смены профессии

Обработка сложных структур данных

Если вложенная структура содержит в себе списки или другие сложные типы данных, задача преобразования усложняется. В таком случае решение можно доработать следующим образом:

Python
Скопировать код
from collections.abc import MutableMapping

def flatten_dict(d, parent_key='', sep='_'):
    items = []
    for k, v in d.items():
        new_key = f'{parent_key}{sep}{k}' if parent_key else k  
        if isinstance(v, MutableMapping):
            items.extend(flatten_dict(v, new_key, sep=sep).items())
        elif isinstance(v, list):
            for i, item in enumerate(v):
                items.extend(flatten_dict({f'{k}_{i}': item}, parent_key, sep=sep).items())
        else:
            items.append((new_key, v))
    return dict(items)

Эта версия функции точно распознает структуры, схожие со словарями, благодаря использованию интерфейса MutableMapping из Python — это повышает надежность типовой проверки.

Упрощение сложных JSON-структур

Если стоит задача обработки сложных JSON-структур, то можно использовать функцию json_normalize из библиотеки Pandas:

Python
Скопировать код
import pandas as pd

def pandas_flatten(json_dict):
    return pd.json_normalize(json_dict, sep='_').to_dict(orient='records')[0]

Этот метод преобразует сложные структуры в словарь, при этом сохраняется высокая эффективность и итерируемость результата.

Предотвращение коллизий ключей

В процессе преобразования могут возникнуть коллизии ключей. Чтобы избежать этого, можно:

  • Присваивать ключам уникальные префиксы, используя, например, их уровень в дереве.
  • Использовать случайность, например, случайные строки или хеши, для обеспечения уникальности ключей.
  • Учитывать контекст данных и выбирать стратегию конкатенации ключей, сообразуясь с его особенностями, например, применяя индексы элементов из списков.

Визуализация

Визуализируем процесс преобразования:

Markdown
Скопировать код
Эскиз домика на дереве:

🌳🏠: 
  ├─ Кухня (🍴)
  |   └─ Шкаф (🚪): [Тарелка 🍽, Кружка ☕️]
  ├─ Спальня (🛏)
      └─ Ящик (🗄): [Носки 🧦, Рубашка 👕]

После преобразования получаем структуру с одним уровнем вложенности:

Markdown
Скопировать код
На первом этаже:

🏠: 
  ├─ Кухня_Шкаф_Тарелка 🍽
  ├─ Кухня_Шкаф_Кружка ☕️
  ├─ Спальня_Ящик_Носки 🧦
  ├─ Спальня_Ящик_Рубашка 👕

Теперь каждый элемент имеет свой уникальный "адрес", указывающий на его местоположение в исходном "дереве".

Примеры на GitHub и кодовые фрагменты

На GitHub вы можете найти все примеры кода, упомянутые в статье. Там же представлены функции для преобразования и тестирования разнообразных типов вложенных словарей и JSON-структур.

Расширение возможностей itertools и more-itertools

Напрямую работать с итераторами помогает библиотека itertools — это важная составляющая процесса преобразования. Библиотека more-itertools предлагает дополнительные инструменты, вроде collapse() для обработки вложенных структур и split_at() для разделения данных по определённым условиям. Использование этих инструментов помогает оптимизировать сложные структуры и более эффективно работать с глубоко вложенными данными.