Ich habe eine dict
, die eine ganze Reihe von Einträgen hat. Ich interessiere mich nur für einige wenige. Gibt es eine einfache Möglichkeit, alle anderen auszuschneiden?
Ich habe eine dict
, die eine ganze Reihe von Einträgen hat. Ich interessiere mich nur für einige wenige. Gibt es eine einfache Möglichkeit, alle anderen auszuschneiden?
Antworten:
Ein neues Diktat konstruieren:
dict_you_want = { your_key: old_dict[your_key] for your_key in your_keys }
Verwendet das Wörterbuchverständnis.
Wenn Sie eine Version verwenden, der sie fehlen (z. B. Python 2.6 und früher), machen Sie es dict((your_key, old_dict[your_key]) for ...)
. Es ist das gleiche, wenn auch hässlicher.
Beachten Sie, dass dies im Gegensatz zur Version von jnnnnn eine stabile Leistung (abhängig nur von der Anzahl Ihrer_Tasten) für old_dict
s jeder Größe aufweist. Sowohl in Bezug auf Geschwindigkeit als auch Speicher. Da dies ein Generatorausdruck ist, verarbeitet er jeweils ein Element 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]
old_dict
auf einen Fehler an anderer Stelle hinweist, und in diesem Fall bevorzuge ich einen Fehler gegenüber stillschweigend falschen Ergebnissen.
Etwas eleganteres Diktatverständnis:
foodict = {k: v for k, v in mydict.items() if k.startswith('foo')}
mydict.iteritems()
stattdessen verwenden. .items()
erstellt eine andere Liste.
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 die if
Anweisung.
Diese Methode ist langsamer als die Antwort von Delnan, wenn Sie nur einige von sehr vielen Tasten auswählen möchten.
if key in ('x','y','z')
denke ich.
Sie können dies mit der Projektfunktion aus meiner Funktionsbibliothek tun :
from funcy import project
small_dict = project(big_dict, keys)
Schauen Sie sich auch select_keys an .
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}
Alle Teile der Codeleistung werden mit timeit unter Verwendung von number = 1000 gemessen und 1000 Mal für jedes Codeteil gesammelt.
Für Python 3.6 ist die Leistung von drei Filterarten fast gleich. Für Python 2.7 ist Code 3 etwas schneller.
Dieser einzeilige 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) vorhanden ist. Ein dict () umschließt das Ganze, um es als dict-Objekt auszugeben.
set
für verwenden wanted_keys
, sieht aber sonst gut aus.
dictfilt({'x':['wefwef',52],'y':['iuefiuef','efefij'],'z':['oiejf','iejf']}, ('x','z'))
, wird es {'x': ['wefwef', 52], 'z': ['oiejf', 'iejf']}
wie beabsichtigt zurückgegeben.
dict={'0':[1,3], '1':[0,2,4], '2':[1,4]}
und das Ergebnis war {}
, was ich als leeres Diktat annahm.
foo = {'0':[1,3], '1':[0,2,4], '2':[1,4]}; dictfilt(foo,('0','2'))
, bekomme ich: {'0': [1, 3], '2': [1, 4]}
was das beabsichtigte Ergebnis ist
Angesichts Ihres Originalwörterbuchs orig
und der Einträge, an denen Sie interessiert sind keys
:
filtered = dict(zip(keys, [orig[k] for k in keys]))
Das ist nicht so schön wie Delnans Antwort, sollte aber in jeder interessierenden Python-Version funktionieren. Es ist jedoch für jedes Element keys
in Ihrem ursprünglichen Wörterbuch fragil .
Basierend auf der akzeptierten Antwort von Delnan.
Was ist, wenn einer Ihrer gewünschten Schlüssel nicht im old_dict enthalten ist? Die Delnan-Lösung löst eine KeyError-Ausnahme aus, die Sie abfangen können. Wenn Sie das nicht brauchen, möchten Sie vielleicht:
Fügen Sie nur Schlüssel hinzu, die sowohl im old_dict als auch in Ihrem Satz von want_keys vorhanden sind.
old_dict = {'name':"Foobar", 'baz':42}
wanted_keys = ['name', 'age']
new_dict = {k: old_dict[k] for k in set(wanted_keys) & set(old_dict.keys())}
>>> new_dict
{'name': 'Foobar'}
haben einen Standardwert für Schlüssel, der nicht in old_dict festgelegt ist.
default = None
new_dict = {k: old_dict[k] if k in old_dict else default for k in wanted_keys}
>>> new_dict
{'age': None, 'name': 'Foobar'}
{k: old_dict.get(k, default) for k in ...}
Diese Funktion erledigt den Trick:
def include_keys(dictionary, keys):
"""Filters a dict by only including certain keys."""
key_set = set(keys) & set(dictionary.keys())
return {key: dictionary[key] for key in key_set}
Genau wie die Version von Delnan verwendet diese Version das Wörterbuchverständnis und bietet eine stabile Leistung für große Wörterbücher (abhängig nur von der Anzahl der zulässigen Schlüssel und nicht von der Gesamtzahl der Schlüssel im Wörterbuch).
Und genau wie die Version von MyGGan ermöglicht diese Version, dass Ihre Liste von Schlüsseln Schlüssel enthält, die möglicherweise nicht im Wörterbuch vorhanden sind.
Und als Bonus ist hier die Umkehrung, wo Sie ein Wörterbuch erstellen können, indem Sie bestimmte Schlüssel im Original ausschließen:
def exclude_keys(dictionary, keys):
"""Filters a dict by excluding certain keys."""
key_set = set(dictionary.keys()) - set(keys)
return {key: dictionary[key] for key in key_set}
Beachten Sie, dass der Vorgang im Gegensatz zur Version von delnan nicht an Ort und Stelle ausgeführt wird, sodass die Leistung von der Anzahl der Schlüssel im Wörterbuch abhängt. Dies hat jedoch den Vorteil, dass die Funktion das bereitgestellte Wörterbuch nicht ändert.
Bearbeiten: Es wurde eine separate Funktion zum Ausschließen bestimmter Tasten von einem Diktat hinzugefügt.
invert
dies, dass das keys
Argument beibehalten wird oder dass das keys
Argument zurückgewiesen wird?", Wie viele von ihnen würden zustimmen?
Wenn wir ein neues Wörterbuch mit entfernten ausgewählten Schlüsseln erstellen möchten, können wir das Wörterbuchverständnis verwenden.
Zum Beispiel:
d = {
'a' : 1,
'b' : 2,
'c' : 3
}
x = {key:d[key] for key in d.keys() - {'c', 'e'}} # Python 3
y = {key:d[key] for key in set(d.keys()) - {'c', 'e'}} # Python 2.*
# x is {'a': 1, 'b': 2}
# y is {'a': 1, 'b': 2}
Andere Option:
content = dict(k1='foo', k2='nope', k3='bar')
selection = ['k1', 'k3']
filtered = filter(lambda i: i[0] in selection, content.items())
Sie erhalten jedoch einen list
(Python 2) oder einen Iterator (Python 3), der von zurückgegeben wird filter()
, nicht einen dict
.
filtered
ein dict
und Sie erhalten das Wörterbuch zurück!
Kurzform:
[s.pop(k) for k in list(s.keys()) if k not in keep]
Wie die meisten Antworten vermuten lassen, müssen wir ein doppeltes Objekt erstellen, sei es ein list
oder , um die Prägnanz aufrechtzuerhalten dict
. Dieser erstellt einen Wegwerfartikel list
, löscht jedoch die Schlüssel im Original dict
.
Hier ist eine weitere einfache Methode, die del
in einem Liner verwendet wird:
for key in e_keys: del your_dict[key]
e_keys
ist die Liste der auszuschließenden Schlüssel. Es wird Ihr Diktat aktualisieren, anstatt Ihnen ein neues zu geben.
Wenn Sie ein neues Ausgabediktat wünschen, erstellen Sie vor dem Löschen eine Kopie des Diktats:
new_dict = your_dict.copy() #Making copy of dict
for key in e_keys: del new_dict[key]
Sie könnten verwenden python-benedict
, es ist eine diktierte Unterklasse.
Installation: pip install python-benedict
from benedict import benedict
dict_you_want = benedict(your_dict).subset(keys=['firstname', 'lastname', 'email'])
Es ist Open Source auf GitHub: https://github.com/fabiocaccamo/python-benedict
Haftungsausschluss: Ich bin der Autor dieser Bibliothek.