Используя модуль Python Glom, извлекайте нерегулярные вложенные списки в единый список словарей

1

Glom облегчает доступ к сложным вложенным структурам данных. https://github.com/mahmoud/glom

Учитывая следующую игрушку структуры данных:

target = [
            {
                'user_id': 198,
                'id': 504508,
                'first_name': 'John',
                'last_name': 'Doe',
                'active': True,
                'email_address': '[email protected]',
                'new_orders': False,
                'addresses': [
                    {
                        'location': 'home',
                        'address': 300,
                        'street': 'Fulton Rd.'
                    }
                ]
            },
            {
                'user_id': 209,
                'id': 504508,
                'first_name': 'Jane',
                'last_name': 'Doe',
                'active': True,
                'email_address': '[email protected]',
                'new_orders': True,
                'addresses': [
                    {
                        'location': 'home',
                        'address': 251,
                        'street': 'Maverick Dr.'
                    },
                    {
                        'location': 'work',
                        'address': 4532,
                        'street':  'Fulton Cir.'
                    },
                ]
            },
        ]

Я пытаюсь извлечь все адресные поля в структуре данных в плоский список словарей.

from glom import glom as glom
from glom import Coalesce
import pprint

"""
Purpose: Test the use of Glom
"""    

# Create Glomspec
spec = [{'address': ('addresses', 'address') }]

# Glom the data
result = glom(target, spec)

# Display
pprint.pprint(result)

Вышеуказанная спецификация обеспечивает:

[
    {'address': [300]},
    {'address': [251]}
]

Желаемый результат:

[
    {'address':300},
    {'address':251},
    {'address':4532}
]

Какой Glomspec даст желаемый результат?

  • 1
    Я не знаю насчет glom , но похоже, что вам нужно только одно понимание списка: [{'address': x['address']} for X in target for x in X['addresses']]
  • 0
    @coldspeed Я знаком со списками и да, это сработало бы, однако эта структура игрушек значительно упрощена, чтобы проиллюстрировать проблему, возникающую у меня с модулем Glom. Glom, кажется, имеет преимущества при работе с очень сложными структурами по сравнению со списком. Я ищу какие-либо сведения о Гломе. Однако, спасибо!
Теги:
data-structures
nested
python-module

1 ответ

2
Лучший ответ

Начиная с glom 19.1.0 вы можете использовать спецификацию Flatten() для краткого получения желаемых результатов:

from glom import glom, Flatten

glom(target,  (['addresses'], Flatten(),  [{'address': 'address'}]))
# [{'address': 300}, {'address': 251}, {'address': 4532}]

И это все, что нужно сделать!

Вы также можете проверить удобную функцию flatten(), а также мощную спецификацию Fold(), для всех ваших потребностей выравнивания :)


До 19.1.0 у glom не было первоклассных возможностей сглаживания или уменьшения (как в картографическом уменьшении). Но одним из обходных путей было бы использование встроенной в Python функции sum() для выравнивания адресов:

>>> from glom import glom, T, Call  # pre-19.1.0 solution
>>> glom(target,  ([('addresses', [T])], Call(sum, args=(T, [])),  [{'address': 'address'}]))
[{'address': 300}, {'address': 251}, {'address': 4532}]

Три шага:

  1. Пройдите по спискам, как вы сделали.
  2. Вызовите сумму в полученном списке, сгладив/уменьшив его.
  3. Отфильтруйте элементы в результирующем списке, чтобы они содержали только ключ 'address'.

Обратите внимание на использование T, которое представляет текущую цель, вроде как курсор.

В любом случае, нет необходимости делать это больше, отчасти из-за этого ответа. Итак, спасибо за отличный вопрос!

  • 1
    Спасибо, Махмуд! Задержитесь при утверждении ответа, чтобы увидеть, что происходит с Sum () и Reduce ()!
  • 0
    Звучит неплохо!
Показать ещё 5 комментариев

Ещё вопросы

Сообщество Overcoder
Наверх
Меню