简体   繁体   English

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

[英]Get value of nested attribute by filtering list on other attribute with Python Glom

I have a data object like this: 我有一个像这样的数据对象:

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

Using glom , I want to get x which is the value of id for the item with name equal to b . 使用glom ,我想得到x ,它是name等于b的项的id的值。

So far, I have this: 到目前为止,我有这个:

from glom import glom
from glom import SKIP


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

Which returns: 哪个返回:

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

I can't figure out what spec (in glom parlance) to use to extract the only element in the returned list and then the value of id . 我无法弄清楚要用什么规范 (用glom )来提取返回列表中的唯一元素,然后提取id的值。

I could call glom twice: 我可以给glom打电话两次:

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

But I figured there should be a way of doing it in one call. 但是我认为应该有一个方法可以一次调用。 Any ideas on how to achieve this? 关于如何实现这一目标的任何想法?

You were very close! 你很亲密! The nice thing about glom chaining (which you're doing with that tuple there), is that you basically never need to call glom twice. 关于glom链(您在那里使用该元组所做的事情)的好处是,您基本上不需要两次调用glom。 You can just chain straight through: 您可以直接链接:

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

All I did was add a third element '0.content.id' , which gets the first item, then the content key, then the id key. 我所做的只是添加了第三个元素'0.content.id' ,它获得了第一项,然后是内容密钥,然后是id密钥。

For a slightly more glom-oriented way, you can rewrite that lambda to the following: 对于面向glom的方式,您可以将该lambda重写为以下内容:

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

It does the same thing and is actually slightly longer, but might read a little better. 它做同样的事情,实际上稍长一些,但阅读起来可能更好一些。 Combine this with another Check for validation, and you can even prevent the final lookup step if no object with the name is found: 将其与另一个Check for validate结合使用,如果未找到名称相同的对象,您甚至可以阻止最后的查找步骤:

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

Don't forget to import Check and STOP if you go that route. 如果您选择该路线, Check不要忘记导入Check and STOP Also, if the spec is getting long, you can give it a nice descriptive variable name :) Thanks for the great question! 另外,如果规范越来越长,您可以给它一个漂亮的描述性变量名称:)谢谢您提出的好问题!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM