Diktat so filtern, dass es nur bestimmte Schlüssel enthält?

Lesezeit: 1 Minute

Benutzer-Avatar
mpen

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?

  • 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

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_dicts 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

Benutzer-Avatar
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


Benutzer-Avatar
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.

Benutzer-Avatar
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 zum wanted_keyssieht 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

Benutzer-Avatar
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.

Geben Sie hier die Bildbeschreibung ein

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 zum wanted_keyssieht 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

Benutzer-Avatar
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

1131740cookie-checkDiktat so filtern, dass es nur bestimmte Schlüssel enthält?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy