2016-11-16 3 views
1

Angenommen, ich habe eine dict wie so:Filterschlüssel von einem dict Wert Werte aus einer Liste mit

d = {27: 32, 28: 41, 29: 29, 30: 29, 31: 67, 32: 65} 

Und eine Liste:

l = [27, 30, 31] 

for n in l: 
      d2 = {k:v for k,v in d.items() if k in n} 

Warum ist dies nicht zulässig? Was kann ich stattdessen tun?

+0

Was meinst du * "nicht erlaubt" *? Warum überprüfen Sie 'k in n' - was würden Sie z.B. '27 in 27'? Meinst du "k in l"? – jonrsharpe

+0

'n' ist eine Ganzzahl, also kann' k' nicht "drin" sein. Möchten Sie stattdessen 'd2 = {k: v für k, v in d.items() wenn k in l}' (ohne die 'for'-Schleife)? –

Antwort

7

Es würde ausreichen, um eine gefilterte dict auf diese Weise zu erhalten:

d = {27: 32, 28: 41, 29: 29, 30: 29, 31: 67, 32: 65} 
l = set([27, 30, 31]) 
d2 = {k:v for k,v in d.items() if k in l} 

print(d2) 

Der Ausgang:

{27: 32, 30: 29, 31: 67} 

Der Ausdruck ... if k in n in Ihrer Liste Verständnis, während sie durch for n in l: Iterieren bedeutet, dass Sie suchen ein numerischer Schlüssel innerhalb einer Ziffer (Zahl) - es ist, als ob wir 27 in 27 suchen, was in diesem Fall sinnlos ist.
Auch set Objekt wäre bei großen Sequenzen vorzuziehen.

Membership testing with sets and dictionaries is much faster, O(1), than searching sequences, O(n)

+0

Drucken d2 gibt einfach zurück: {31: 0} aus irgendeinem Grund – user1893110

+0

@ user1893110 Verwenden Sie den genauen Code oben ... Ihre 'for' Schleife verursacht das Problem. –

+0

Einfach genug. Für Leistungszwecke würde ich ein Set anstelle einer Liste verwenden, aber das ist so klein, dass es keinen Unterschied macht. – Goodies

0

Nun, es ist ein Tippfehler in Ihrem Code:

d2 = {k:v for k,v in d.items() if k in n} 

if k in n produziert

TypeError: argument of type 'int' is not iterable

weil in kann nur auf ein iterable Objekt angewendet werden. Wenn Sie es

d2 = {k:v for k,v in d.items() if k == n} 

es richtig funktioniert und

d2
{31: 67}

+0

Aber ich würde auch erwarten, dass es den Schlüssel: Wert-Paare für 27 und 30 – user1893110

+0

@ user1893110 als Sie sollten nicht in jeder Iteration neu zuweisen, sondern zum Wörterbuch stattdessen –

2

die effizienteste Art und Weise zu tun, was Sie wollen, ist produzieren ändern:

d2 = {k:d[k] for k in l} 

Wenn es möglich ist, dass l enthält Artikel, die keine Schlüssel in d sind:

d2 = {k:d[k] for k in l if k in d} 
+0

würde ergeben wenn ein 'KeyError' ausgelöst wird, wenn irgendeines in 'l' nicht auch in 'd' ist. – Goodies

+1

@Goodies danke, bearbeitet. –

Verwandte Themen