Reputation: 13
I have an api call that returns a dictionary with all the ids for all users
and others to get the userDetails
like:
>>> allIds=api.getAllIds()
{1,2,3,4,5}
>>> userDetails=api.getUserDetails(1)
{'name':'Bob','age':'19'}
I'm trying to pack the whole structure in a dict with the userId
-like key and the info-like value.
I could make it work with:
>>> users={id:api.getUserDetails(id) for id in allIds}
{1:{'name':'bob','age':'19'},2:None,3:{'name':'alice','age':'21'},...}
The problem is that not all Ids returns a response as you can see for the id 2 call. I'm trying not to use traditional loops and I'm solving the situation cleaning the resulting dict
after the calls with:
>>> users=[id:users[id] for id in users.keys() if users[id]!=None]
It's working, but I'm trying not to put inside the empty values instead of cleaning. In a normal situation you could create the dict like:
>>> a=[id:b[id] for id in b.keys() if b[id]!=None ]
But in my case if I check if b[i]
is None... then I'm calling the api two times because my b[i]
expression is api.getUserDetails(id)
, one to take the value and the other to check if is not None.
So I'm trying something like nested dictionary comprehension:
users = {(x,y) for x in usersIds for y in api.getUserDetails(x) if y!=None }
But I can not make it work.
Anyone know how to do it?
Upvotes: 1
Views: 1750
Reputation: 78546
You can put the result of the api call in a singleton tuple:
users = {x: y for x in usersIds for y in (api.getUserDetails(x),) if y is not None}
Demo:
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}
However, it is pretty wasteful to set up a nested loop for such and may be more readable to use a vanilla for
loop to build the dictionary:
users = {}
for x in usersIds:
y = api.getUserDetails(x)
if y is not None:
users[x] = y
Upvotes: 4