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}
]
Начиная с 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}]
Три шага:
'address'
. Обратите внимание на использование T
, которое представляет текущую цель, вроде как курсор.
В любом случае, нет необходимости делать это больше, отчасти из-за этого ответа. Итак, спасибо за отличный вопрос!
glom
, но похоже, что вам нужно только одно понимание списка:[{'address': x['address']} for X in target for x in X['addresses']]