Используя модуль Python Glom, извлекайте нерегулярные вложенные списки в единый список словарей - PullRequest
0 голосов
/ 01 ноября 2018

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

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

target = [
            {
                'user_id': 198,
                'id': 504508,
                'first_name': 'John',
                'last_name': 'Doe',
                'active': True,
                'email_address': 'jd@test.com',
                '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': 'jd@test.com',
                '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 Ответ

0 голосов
/ 11 января 2019

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

from glom import glom, Flatten

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

И это все, что нужно!

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


До 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, которое представляет текущую цель, как курсор.

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

...