Вложенное словарное понимание, чтобы избежать пустых значений

У меня есть вызов API, который возвращает словарь со всеми идентификаторами для всех пользователей и других, чтобы получить userDetails лайк:

>>> allIds=api.getAllIds()
{1,2,3,4,5}
>>> userDetails=api.getUserDetails(1)
{'name':'Bob','age':'19'}

Я пытаюсь упаковать всю структуру в диктанте с userId-подобный ключ и информационное значение.

Я мог бы заставить его работать с:

>>> users={id:api.getUserDetails(id) for id in allIds}
{1:{'name':'bob','age':'19'},2:None,3:{'name':'alice','age':'21'},...}

Проблема в том, что не все идентификаторы возвращают ответ, как вы можете видеть для вызова id 2. Я стараюсь не использовать традиционные циклы, и я решаю ситуацию, очищая получившийся dict после звонков с:

>>> users=[id:users[id] for id in users.keys() if users[id]!=None]

Это работает, но я стараюсь не помещать пустые значения вместо очистки. В нормальной ситуации вы можете создать такой диктовку, как:

>>> a=[id:b[id] for id in b.keys() if b[id]!=None ]

Но в моем случае, если я проверю, b[i] Нет... тогда я вызываю API два раза, потому что мой b[i] выражение api.getUserDetails(id)один для получения значения, а другой для проверки, если не None.

Итак, я пытаюсь что-то вроде понимания вложенного словаря:

users = {(x,y) for x in usersIds for y in api.getUserDetails(x) if y!=None }

Но я не могу заставить его работать.

Кто-нибудь знает, как это сделать?

1 ответ

Решение

Вы можете поместить результат вызова API в одноэлементный кортеж:

users = {x: y for x in usersIds for y in (api.getUserDetails(x),) if y is not None}

Демо-версия:

lst = [(5,6), (2,None)]
d = {k: v for k, x in lst for v in (x,) if v is not None}
print(d)
# {5: 6}

Тем не менее, для этого достаточно расточительно настроить вложенный цикл и может быть более читабельным использование ванили for цикл для построения словаря:

users = {}
for x in usersIds:
    y = api.getUserDetails(x)
    if y is not None:
        users[x] = y
Другие вопросы по тегам