Получить значение вложенного атрибута путем фильтрации списка по другому атрибуту с помощью Python Glom - PullRequest
0 голосов
/ 07 января 2019

У меня есть такой объект данных:

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.

Я мог бы дважды вызвать Глома:

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

Но я подумал, что должен быть способ сделать это за один звонок. Есть идеи как этого добиться?

1 Ответ

0 голосов
/ 11 января 2019

Вы были очень близки! Хорошая особенность цепочки glom (которую вы делаете с этим кортежем) заключается в том, что вам по сути никогда не нужно вызывать glom дважды. Вы можете просто соединиться прямо:

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

Все, что я сделал, это добавил третий элемент '0.content.id', который получает первый элемент, затем ключ содержимого, затем ключ id.

Для немного более привлекательного способа вы можете переписать эту лямбду следующим образом:

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

Он делает то же самое и на самом деле немного длиннее, но может читать немного лучше. Объедините это с другой проверкой для проверки, и вы даже можете предотвратить последний шаг поиска, если не найден объект с именем:

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

Не забудьте импортировать Check и STOP, если вы пойдете по этому пути. Кроме того, если спецификация становится длинной, вы можете дать ей хорошее описательное имя переменной :) Спасибо за отличный вопрос!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...