470 Stimmen

Teilmenge von Schlüssel-Wert-Paaren aus Wörterbuch extrahieren?

Ich habe ein großes Wörterbuch-Objekt, das mehrere Schlüssel-Wert-Paare (etwa 16) hat, aber ich bin nur an 3 von ihnen interessiert. Was ist der beste Weg (kürzeste/effizienteste/eleganteste), um das zu erreichen?

Das Beste, was ich weiß, ist:

bigdict = {'a':1,'b':2,....,'z':26} 
subdict = {'l':bigdict['l'], 'm':bigdict['m'], 'n':bigdict['n']}

Ich bin sicher, dass es einen eleganteren Weg als diesen gibt.

2voto

DmitrySemenov Punkte 7732

Lösung

from operator import itemgetter
from typing import List, Dict, Union

def subdict(d: Union[Dict, List], columns: List[str]) -> Union[Dict, List[Dict]]:
    """Return a dict or list of dicts with subset of 
    columns from the d argument.
    """
    getter = itemgetter(*columns)

    if isinstance(d, list):
        result = []
        for subset in map(getter, d):
            record = dict(zip(columns, subset))
            result.append(record)
        return result
    elif isinstance(d, dict):
        return dict(zip(columns, getter(d)))

    raise ValueError('Unsupported type for `d`')

Anwendungsbeispiele

# pure dict

d = dict(a=1, b=2, c=3)
print(subdict(d, ['a', 'c']))

>>> In [5]: {'a': 1, 'c': 3}

# list of dicts

d = [
    dict(a=1, b=2, c=3),
    dict(a=2, b=4, c=6),
    dict(a=4, b=8, c=12),
]

print(subdict(d, ['a', 'c']))

>>> In [5]: [{'a': 1, 'c': 3}, {'a': 2, 'c': 6}, {'a': 4, 'c': 12}]

1voto

ntg Punkte 10508

Die Verwendung der Karte (halfdanrumps Antwort) ist für mich am besten, obwohl ich die Zeit nicht gemessen habe...

Aber wenn Sie sich für ein Wörterbuch entscheiden, und wenn Sie ein big_dict:

  1. Vergewissern Sie sich unbedingt, dass Sie die Anforderungen durchlaufen haben. Dies ist entscheidend und wirkt sich auf die Laufzeit des Algorithmus aus (Big O, Theta, usw.)
  2. Schreiben Sie sie allgemein genug, um Fehler zu vermeiden, wenn Schlüssel nicht vorhanden sind.

so z.B.:

big_dict = {'a':1,'b':2,'c':3,................................................}
req = ['a','c','w']

{k:big_dict.get(k,None) for k in req )
# or 
{k:big_dict[k] for k in req if k in big_dict)

Beachten Sie, dass Sie im umgekehrten Fall, d. h. wenn req groß, my_dict aber klein ist, stattdessen eine Schleife über my_dict ziehen sollten.

Im Allgemeinen machen wir eine Kreuzung und die Komplexität des Problems ist O(min(len(dict)),min(len(req))) . Pythons eigene Umsetzung der Kreuzung berücksichtigt die Größe der beiden Mengen, so dass es optimal erscheint. Da sie in C und Teil der Kernbibliothek ist, ist sie außerdem wahrscheinlich schneller als die meisten nicht optimierten Python-Anweisungen. Daher ist eine Lösung, die ich in Betracht ziehen würde:

dict = {'a':1,'b':2,'c':3,................................................}
req = ['a','c','w',...................]

{k:dic[k] for k in set(req).intersection(dict.keys())}

Es verlagert die kritische Operation in den c-Code von Python und wird in allen Fällen funktionieren.

1voto

Für den Fall, dass jemand die ersten paar Artikel haben möchte n des Wörterbuchs, ohne die Schlüssel zu kennen:

n = 5 # First Five Items
ks = [*dikt.keys()][:n]
less_dikt = {i: dikt[i] for i in ks}

0 Stimmen

Dies ist eine gute Möglichkeit, einen Abschnitt aus einem großen Wörterbuch herauszuschneiden.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X