1

ich einen API-Aufruf, die ein Wörterbuch mit allen IDs für alle Benutzer zurückgibt und andere das bekommen userDetails wie:Nested Wörterbuch Verständnis auf leere Werte zu vermeiden

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

Ich versuche, das ganze zu packen Struktur in einem Dict mit dem userId -ähnlichen Schlüssel und dem infoähnlichen Wert.

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

Das Problem ist, dass nicht alle Ids gibt eine Antwort, wie Sie für die ID 2 Anruf sehen:

Ich konnte es mit arbeiten. Ich versuche nicht, traditionelle Schleifen zu verwenden, und ich bin die Situation Lösung mit den resultierenden dict nach dem Anruf Reinigung:

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

Es funktioniert, aber ich versuche nicht statt Reinigung im Innern der leeren Werte zu setzen . In einer normalen Situation könnte man die dict wie erstellen:

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

Aber in meinem Fall, wenn ich überprüfe, ob b[i] None ... dann bin ich rufe die api zwei Mal, weil mein b[i] Ausdruck api.getUserDetails(id) ist, ein bis Nimm den Wert und den anderen, um zu prüfen, ob es keine gibt.

So etwas wie verschachtelt Wörterbuch Verständnis Ich versuche:

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

Aber ich kann es nicht machen.

Wer weiß, wie es geht?

+1

Vergleichen Sie mit ohne mit 'ist'. Und 'users = {id: api.getUserDetails (id) für id in allIds, wenn api.getUserDetails (id) nicht None}' sollte funktionieren –

+0

@ MaartenFabré Er sagte, er wolle vermeiden, 'api.getUserDetails (id)' zweimal aufzurufen : _ "Aber in meinem Fall, wenn ich überprüfe, ob b [i] ist keine ... dann rufe ich die api zweimal [...]." _. –

+0

da Sie nicht innerhalb eines Verständnisses zuweisen können, müssten Sie entweder eine sinnvolle, cleaning Verständnis 'Benutzer = {Schlüssel: Wert für Schlüssel, Wert in users.items(), wenn Wert ist keine}, arbeiten mit einem echten für -loop oder mit einer externen Generatorfunktion –

Antwort

4

Sie können das Ergebnis des API-Aufrufs in einem Singleton Tupel setzen:

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} 

Allerdings ist es ziemlich verschwenderisch ein einzurichten geschachtelte Schleife für solche und möglicherweise besser lesbar, um eine Vanille for Schleife zu verwenden, um das Wörterbuch zu erstellen:

users = {} 
for x in usersIds: 
    y = api.getUserDetails(x) 
    if y is not None: 
     users[x] = y 
+1

Dang es, war gerade dabei, die gleiche Sache zu posten. Beat mich zu;) +1 –

+0

Sehr interessant. Was meinst du mit Verschwendung? In Bezug auf die Leistungen? Verständnis ist in der Regel schneller als Schleifen, soweit ich weiß, ist das Einfügen in ein Tupel so teuer? –

+1

@AndoJurai Das verschachtelte * für * dient nur dazu, das Ergebnis des 'api'-Aufrufs beizubehalten, genau wie eine Zuweisung. Es dient keinem anderen Zweck. Beachten Sie, wie ein Tupel mit einem einzelnen Element erstellt wird. –

Verwandte Themen