Ich habe ein dict
das hat eine ganze Reihe von Einträgen. Ich interessiere mich nur für einige wenige davon. Gibt es eine einfache Möglichkeit, alle anderen herauszuschneiden?
Diktat so filtern, dass es nur bestimmte Schlüssel enthält?
mpen
Erstellen eines neuen Diktats:
dict_you_want = { your_key: old_dict[your_key] for your_key in your_keys }
Verwendet Wörterbuchverständnis.
Wenn Sie eine Version verwenden, der sie fehlen (dh Python 2.6 und früher), machen Sie es dict((your_key, old_dict[your_key]) for ...)
. Es ist dasselbe, wenn auch hässlicher.
Beachten Sie, dass dies im Gegensatz zur Version von jnnnnn eine stabile Leistung hat (hängt nur von der Anzahl Ihrer_Schlüssel ab). old_dict
s jeder Größe. Sowohl in Bezug auf Geschwindigkeit als auch auf Speicher. Da dies ein Generatorausdruck ist, verarbeitet er ein Element nach dem anderen und durchsucht nicht alle Elemente von old_dict.
Alles an Ort und Stelle entfernen:
unwanted = set(keys) - set(your_dict)
for unwanted_key in unwanted: del your_dict[unwanted_key]
-
“Verwendet Wörterbuchverständnis, wenn Sie eine Version verwenden, der diese fehlen” == Version <= 2.6
– getekha
10. November 2011 um 10:11 Uhr
-
Löst einen KeyError aus, wenn einer der Filer-Schlüssel nicht in old_dict vorhanden ist. Ich würde {k:d[k] für k in Filter wenn k in d}
– Peter Gibson
28. Juni 2012 um 1:53 Uhr
-
@PeterGibson Ja, wenn dies Teil der Anforderungen ist, müssen Sie dies tun etwas darüber. Ob es sich um das stille Löschen der Schlüssel, das Hinzufügen eines Standardwerts oder etwas anderes handelt, hängt davon ab, was Sie tun. Es gibt viele Anwendungsfälle, in denen Ihr Ansatz falsch ist. Es gibt auch viele, bei denen ein Schlüssel fehlt
old_dict
weist auf einen Fehler an anderer Stelle hin, und in diesem Fall ziehe ich einen Fehler sehr viel vor stillschweigend falschen Ergebnissen.– Benutzer395760
29. Juni 2012 um 17:12 Uhr
-
@PeterGibson Tut es nicht, die Wörterbuchsuche ist O (1).
– Benutzer395760
1. Juli 2012 um 10:48 Uhr
-
nit: Wörterbücher sind Hash-Maps, also ist der Normalfall O(1). Der schlimmste (höchst unwahrscheinliche) Fall ist O(n), hängt aber von der Wahrscheinlichkeit einer Hash-Kollision ab. Sie würden ein astronomisch großes Wörterbuch oder einen wirklich groben Hash-Algorithmus benötigen, um zu erkennen, dass dies ein Problem darstellt. stackoverflow.com/a/1963514/1335793
– Davos
5. Oktober 2017 um 12:57 Uhr
Etwas eleganteres Diktatverständnis:
foodict = {k: v for k, v in mydict.items() if k.startswith('foo')}
-
Hochgestimmt. Ich habe darüber nachgedacht, eine ähnliche Antwort hinzuzufügen. Nur aus Neugier, warum sollte {k:v for k,v in dict.items() …} statt {k:dict[k] for k in dict …} Gibt es einen Leistungsunterschied?
– Hart Simha
24. Juni 2014 um 17:30 Uhr
-
Meine eigene Frage beantwortet. Das {k:dict[k] for k in dict …} ist etwa 20-25 % schneller, zumindest in Python 2.7.6, mit einem Wörterbuch von 26 Einträgen (timeit(…, setup=”d = {chr(x+97): x+1 für x im Bereich (26)}”)), je nachdem, wie viele Elemente herausgefiltert werden (das Herausfiltern von Konsonantenschlüsseln ist schneller als das Herausfiltern von Vokalschlüsseln, da Sie weniger Elemente nachschlagen). Der Leistungsunterschied kann mit zunehmender Größe Ihres Wörterbuchs sehr wohl an Bedeutung verlieren.
– Hart Simha
24. Juni 2014 um 18:13 Uhr
-
Wäre wahrscheinlich die gleiche Leistung, wenn Sie verwendet würden
mydict.iteritems()
stattdessen..items()
erstellt eine weitere Liste.– Pat
16. Juni 2016 um 22:47 Uhr
jnnnn
Hier ist ein Beispiel in Python 2.6:
>>> a = {1:1, 2:2, 3:3}
>>> dict((key,value) for key, value in a.iteritems() if key == 1)
{1: 1}
Der Filterteil ist der if
Aussage.
Diese Methode ist langsamer als die Antwort von delnan, wenn Sie nur wenige von sehr vielen Tasten auswählen möchten.
-
außer ich würde wahrscheinlich verwenden
if key in ('x','y','z')
Ich vermute.– mp
6. August 2010 um 0:17 Uhr
-
Wenn Sie bereits wissen, welche Schlüssel Sie möchten, verwenden Sie die Antwort von delnan. Wenn Sie jeden Schlüssel mit einer if-Anweisung testen müssen, verwenden Sie die Antwort von ransford.
– jnnnn
19. September 2015 um 8:02 Uhr
-
Diese Lösung hat noch einen weiteren Vorteil. Wenn das Wörterbuch von einem teuren Funktionsaufruf zurückgegeben wird (dh a/old_dict ist ein Funktionsaufruf), ruft diese Lösung die Funktion nur einmal auf. In einer imperativen Umgebung ist das Speichern des von der Funktion zurückgegebenen Wörterbuchs in einer Variablen keine große Sache, aber in einer funktionalen Umgebung (z. B. in einem Lambda) ist dies eine wichtige Beobachtung.
– gae123
27. Januar 2016 um 1:11 Uhr
Suor
Das kannst du mit Projekt Funktion von meiner lustig Bibliothek:
from funcy import project
small_dict = project(big_dict, keys)
Schau auch mal rein select_keys.
Jim
Dieses Einzeiler-Lambda sollte funktionieren:
dictfilt = lambda x, y: dict([ (i,x[i]) for i in x if i in set(y) ])
Hier ist ein Beispiel:
my_dict = {"a":1,"b":2,"c":3,"d":4}
wanted_keys = ("c","d")
# run it
In [10]: dictfilt(my_dict, wanted_keys)
Out[10]: {'c': 3, 'd': 4}
Es ist ein grundlegendes Listenverständnis, das über Ihre Diktatschlüssel (i in x) iteriert und eine Liste von Tupelpaaren (Schlüssel, Wert) ausgibt, wenn der Schlüssel in Ihrer gewünschten Schlüsselliste (y) enthalten ist. Ein dict() umschließt das Ganze, um es als dict-Objekt auszugeben.
-
Sollte a verwenden
set
zumwanted_keys
sieht aber sonst gut aus.– mp
28. November 2013 um 2:35 Uhr
-
Dies gibt mir ein leeres Wörterbuch, wenn mein ursprüngliches Wörterbuch Listen anstelle von Werten enthält. Irgendwelche Problemumgehungen?
– FaKaffee
27. Oktober 2015 um 13:35 Uhr
-
@Francesco, kannst du ein Beispiel geben? Wenn ich laufe:
dictfilt({'x':['wefwef',52],'y':['iuefiuef','efefij'],'z':['oiejf','iejf']}, ('x','z'))
es kehrt zurück{'x': ['wefwef', 52], 'z': ['oiejf', 'iejf']}
wie beabsichtigt.– Jim
28. Oktober 2015 um 14:11 Uhr
-
Ich habe das versucht mit:
dict={'0':[1,3], '1':[0,2,4], '2':[1,4]}
und das Ergebnis war{}
von dem ich annahm, dass es sich um ein leeres Diktat handelte.– FaKaffee
28. Oktober 2015 um 14:15 Uhr
-
Eine Sache, “dict” ist ein reserviertes Wort, also sollten Sie es nicht verwenden, um ein Diktat zu benennen. Was waren die Schlüssel, die Sie herausziehen wollten? Wenn ich laufe:
foo = {'0':[1,3], '1':[0,2,4], '2':[1,4]}; dictfilt(foo,('0','2'))
Ich bekomme:{'0': [1, 3], '2': [1, 4]}
was das beabsichtigte Ergebnis ist– Jim
28. Oktober 2015 um 20:22 Uhr
JJ
Code 1:
dict = { key: key * 10 for key in range(0, 100) }
d1 = {}
for key, value in dict.items():
if key % 2 == 0:
d1[key] = value
Code 2:
dict = { key: key * 10 for key in range(0, 100) }
d2 = {key: value for key, value in dict.items() if key % 2 == 0}
Code 3:
dict = { key: key * 10 for key in range(0, 100) }
d3 = { key: dict[key] for key in dict.keys() if key % 2 == 0}
Die Leistung aller Codeteile wird mit timeit unter Verwendung von Zahl = 1000 gemessen und 1000 Mal für jedes Codeteil erfasst.
Für Python 3.6 ist die Leistung von drei Arten von Filter-Dict-Keys fast gleich. Für Python 2.7 ist Code 3 etwas schneller.
-
Sollte a verwenden
set
zumwanted_keys
sieht aber sonst gut aus.– mp
28. November 2013 um 2:35 Uhr
-
Dies gibt mir ein leeres Wörterbuch, wenn mein ursprüngliches Wörterbuch Listen anstelle von Werten enthält. Irgendwelche Problemumgehungen?
– FaKaffee
27. Oktober 2015 um 13:35 Uhr
-
@Francesco, kannst du ein Beispiel geben? Wenn ich laufe:
dictfilt({'x':['wefwef',52],'y':['iuefiuef','efefij'],'z':['oiejf','iejf']}, ('x','z'))
es kehrt zurück{'x': ['wefwef', 52], 'z': ['oiejf', 'iejf']}
wie beabsichtigt.– Jim
28. Oktober 2015 um 14:11 Uhr
-
Ich habe das versucht mit:
dict={'0':[1,3], '1':[0,2,4], '2':[1,4]}
und das Ergebnis war{}
von dem ich annahm, dass es sich um ein leeres Diktat handelte.– FaKaffee
28. Oktober 2015 um 14:15 Uhr
-
Eine Sache, “dict” ist ein reserviertes Wort, also sollten Sie es nicht verwenden, um ein Diktat zu benennen. Was waren die Schlüssel, die Sie herausziehen wollten? Wenn ich laufe:
foo = {'0':[1,3], '1':[0,2,4], '2':[1,4]}; dictfilt(foo,('0','2'))
Ich bekomme:{'0': [1, 3], '2': [1, 4]}
was das beabsichtigte Ergebnis ist– Jim
28. Oktober 2015 um 20:22 Uhr
Kai
Angesichts Ihres ursprünglichen Wörterbuchs orig
und den Satz von Einträgen, an denen Sie interessiert sind keys
:
filtered = dict(zip(keys, [orig[k] for k in keys]))
Das ist nicht so schön wie die Antwort von delnan, sollte aber in jeder interessanten Python-Version funktionieren. Es ist jedoch für jedes Element zerbrechlich keys
in Ihrem ursprünglichen Wörterbuch vorhanden sind.
-
Nun, dies ist im Grunde eine eifrige Version der “Tupelgenerator-Version” meines Diktatverständnisses. In der Tat sehr kompatibel, obwohl Generatorausdrücke in 2.4, Frühjahr 2005 eingeführt wurden – im Ernst, verwendet das noch jemand?
– Benutzer395760
6. August 2010 um 1:20 Uhr
-
Ich bin nicht anderer Meinung; 2.3 sollte es eigentlich nicht mehr geben. Als veraltete Umfrage zur 2.3-Nutzung gilt jedoch: moinmo.in/PollAboutRequiringPython24 Kurzversion: RHEL4, SLES9, ausgeliefert mit OS X 10.4
– Kai
6. August 2010 um 3:51 Uhr
Es ist hilfreich zu sagen, welche Art von Schlüsseln (Ganzzahlen? Zeichenfolgen? Datumsangaben? beliebige Objekte?) und ob es einen einfachen Test (Zeichenfolge, Regex, Listenmitgliedschaft oder numerische Ungleichheit) gibt, um zu überprüfen, welche Schlüssel ein- oder ausgeschaltet sind. Oder wir müssen eine oder mehrere beliebige Funktionen aufrufen, um dies zu bestimmen.
– smci
14. November 2019 um 23:09 Uhr
@smci Zeichenfolgenschlüssel. Glaubt nicht, dass mir auch nur eingefallen wäre, dass ich etwas anderes gebrauchen könnte; Ich habe so lange in JS und PHP programmiert…
– mp
15. November 2019 um 0:48 Uhr