使用Python模块Glom,将不规则的嵌套列表提取到平坦的字典列表中

时间:2018-11-01 20:07:04

标签: python data-structures nested python-module

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 :(得分:2)

从glom 19.1.0开始,您可以使用Flatten() spec简洁地获得所需的结果:

from glom import glom, Flatten

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

仅此而已!

您可能还想查看the convenient flatten() function和功能强大的Fold() spec,以满足您的所有扁平化需求:)


在19.1.0之前,glom没有一流的展平或缩小(如map-reduce)功能。但是一种解决方法是使用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的用法,它代表当前目标,有点像光标。

无论如何,部分由于这个答案,所以不再需要这样做。所以,谢谢你提出的好问题!