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

Pab*_*blo 3 python json glom

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

data = {
    'props': {
        'items': [
            {'name': 'a', 'content': 'plain'},
            {'name': 'b', 'content': {'id': 'x'}},
            {'name': 'c', 'content': {'id': 'y'}},
        ]
    }
}
Run Code Online (Sandbox Code Playgroud)

使用glom,我想获得等于的项目x的值。idnameb

到目前为止,我有这个:

from glom import glom
from glom import SKIP


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

返回:

[{'name': 'b', 'content': {'id': 'x'}}]
Run Code Online (Sandbox Code Playgroud)

我无法弄清楚使用什么规范(用glom说法)来提取返回列表中的唯一元素,然后提取id.

我可以调用 glom 两次:

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

但我认为应该有一种方法可以在一个电话中做到这一点。关于如何实现这一目标的任何想法?

Mah*_*emi 6

你非常接近!glom 链接(你在那里用那个元组做的)的好处是你基本上不需要调用 glom 两次。您可以直接链接:

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

我所做的只是添加第三个 element '0.content.id',它获取第一项,然后是内容键,然后是 id 键。

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

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

它做同样的事情,实际上稍长一些,但可能读起来更好一点。将此与另一个检查验证结合起来,如果没有找到具有该名称的对象,您甚至可以阻止最后的查找步骤:

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

不要忘记导入CheckSTOP如果你走那条路。此外,如果规范越来越长,您可以给它一个很好的描述性变量名称:) 感谢您提出的好问题!