通过使用Python Glom过滤其他属性上的列表来获取嵌套属性的值

时间:2019-01-07 16:23:21

标签: python json

我有一个这样的数据对象:

data = {
    'props': {
        'items': [
            {'name': 'a', 'content': 'plain'},
            {'name': 'b', 'content': {'id': 'x'}},
            {'name': 'c', 'content': {'id': 'y'}},
        ]
    }
}

我要使用glom来获取x,它是id等于name的项目的b值。

到目前为止,我有这个:

from glom import glom
from glom import SKIP


glom(data, ('props.items', [lambda i: i if i['name']=='b' else SKIP]))

哪个返回:

[{'name': 'b', 'content': {'id': 'x'}}]

我无法弄清楚要用什么 spec (用glom来提取返回列表中的唯一元素,然后提取id的值。 / p>

我可以打电话给格洛姆两次:

glom(glom(data, ('props.items', [lambda i: i if i['name']=='b' else SKIP]))[0], 'content.id')

但是我认为应该有一个方法可以一次调用。关于如何实现这一目标的任何想法?

1 个答案:

答案 0 :(得分:3)

您非常亲密!关于glom链(您在那里使用该元组所做的事情)的好处是,您基本上不需要两次调用glom。您可以直接链接:

>>> glom(data, ('props.items', [lambda i: i if i['name']=='b' else SKIP], '0.content.id'))
'x'

我所做的就是添加第三个元素'0.content.id',该元素将获取第一项,然后是内容密钥,然后是id密钥。

对于面向glom的方式,您可以将该lambda重写为以下内容:

>>> glom(data, ('props.items', [Check('name', equal_to='b', default=SKIP)], '0.content.id'))
'x'

它做同样的事情,实际上更长一些,但阅读起来可能更好一些。将其与另一个Check for validate结合使用,如果找不到名称相同的对象,甚至可以阻止最后的查找步骤:

>>> glom(data, ('props.items', [Check('name', equal_to='z', default=SKIP)], Check(default=STOP), '0.content.id'))
[]

如果走那条路,别忘了导入CheckSTOP。另外,如果规格变长,您可以给它一个漂亮的描述性变量名称:)谢谢您提出的好问题!