Python diktiert, wie ein Schlüssel erstellt oder ein Element an den Schlüssel angehängt wird.

161

Ich habe ein leeres Wörterbuch. Name: dict_x Es müssen Schlüssel vorhanden sein, deren Werte Listen sind.

Aus einer separaten Iteration erhalte ich einen Schlüssel (z. B. key_123:) und ein Element (ein Tupel), das in die Liste des dict_xWertes eingefügt werden soll key_123.

Wenn dieser Schlüssel bereits vorhanden ist, möchte ich diesen Artikel anhängen. Wenn dieser Schlüssel nicht vorhanden ist, möchte ich ihn mit einer leeren Liste erstellen und dann an ihn anhängen oder ihn einfach mit einem Tupel erstellen.

Wenn dieser Schlüssel in Zukunft erneut angezeigt wird, möchte ich, dass der Wert erneut angehängt wird, da er vorhanden ist.

Mein Code besteht aus:

Holen Sie sich Schlüssel und Wert.

Überprüfen Sie, ob der Schlüssel NOT in vorhanden ist dict_x.

und wenn nicht erstellen: dict_x[key] == []

Danach: dict_x[key].append(value)

Ist das der Weg, es zu tun? Soll ich versuchen, try/exceptBlöcke zu verwenden ?

Phil
quelle

Antworten:

253

Verwendung dict.setdefault():

dic.setdefault(key,[]).append(value)

Hilfe (dict.setdefault) :

    setdefault(...)
        D.setdefault(k[,d]) -> D.get(k,d), also set D[k]=d if k not in D
Ashwini Chaudhary
quelle
4
Früher habe ich das gemacht, dict_x[key] = [some_value] if not dict_x.has_key(key) else dict_x[key] + [some_value]aber diese Antwort schlägt einen weitaus besseren Weg vor. In der Tat wird es set()als Argument und ermöglicht es Ihnen, add()Methode zu verwenden ...
fatih_dur
66

Hier sind die verschiedenen Möglichkeiten, um dies zu tun, damit Sie vergleichen können, wie es aussieht, und auswählen können, was Ihnen gefällt. Ich habe sie auf eine Weise bestellt, die ich für am "pythonischsten" halte , und die Vor- und Nachteile kommentiert, die auf den ersten Blick nicht offensichtlich sind:

Verwenden von collections.defaultdict:

import collections
dict_x = collections.defaultdict(list)

...

dict_x[key].append(value)

Vorteile: Wahrscheinlich beste Leistung. Nachteile: Nicht verfügbar in Python 2.4.x.

Verwenden von dict().setdefault():

dict_x = {}

...

dict_x.setdefault(key, []).append(value)

Nachteile: Ineffiziente Erstellung nicht verwendeter list()s.

Verwenden von try ... except:

dict_x = {}

...

try:
    values = dict_x[key]
except KeyError:
    values = dict_x[key] = []
values.append(value)

Oder:

try:
    dict_x[key].append(value)
except KeyError:
    dict_x[key] = [value]
Antak
quelle
Hallo, warum erstellt .setdefault Ihrer Meinung nach unnötige Wörterbücher?
Phil
2
Ich denke nicht, dass .setdefault()unnötige Wörterbücher erstellt werden. Ich denke, ich erstelle unnötige lists (dh []) im zweiten Argument .setdefault(), das nie verwendet wird, wenn es keybereits existiert. Ich könnte dict.setdefault()(zum Vorteil eines effizienten Schlüssel-Hashing) eine Variable verwenden, um nicht verwendete lists wiederzuverwenden, aber das fügt ein paar weitere Codezeilen hinzu.
Antak
1
IIRC: In Python wird eine leere Liste in einer Gleichheit als Konstante auf Bytecode-Ebene betrachtet. Dies muss jedoch von einem Bytecode-Guru bestätigt werden (oder verwenden Sie einfach das Disas-Modul).
gaborous
Die Verwendung von .setdefaulterstellt eine regelmäßige dictSuche nach fehlenden Schlüsseln, führt zu einer KeyErrorWeile, wo collections.defaultdict(list)eine dictSuche nach fehlenden Schlüsseln erstellt wird, fügt eine leere ein list- ich denke, Sie sollten basierend auf dem gewünschten Verhalten auswählen
Chris_Rands
Ich habe etwas Ähnliches wie collection.defaultdict in meinem eigenen Code ausprobiert und es hatte unerwartete Nebenwirkungen. Betrachten Sie zum Beispiel den folgenden IDLE-Austausch: >>> list_dict = defaultdict (Liste) >>> len (list_dict) 0 >>> len (list_dict [0]) 0 >>> len (list_dict) 1 Es scheint, dass wenn Python aufruft Der Standardwert, mit dem der Schlüssel zum Wörterbuch hinzugefügt wird, ohne dass Sie ihn aktiv festlegen. Dadurch werden viele leere Listen erstellt, wenn der Standardwert häufig verwendet wird. Ich werde meine eigenen Wrapper-Funktionen für das Wörterbuch rollen, ineffizient, aber hoffentlich vorhersehbarer.
RDBury
26

Sie können hierfür ein Standarddikt verwenden .

from collections import defaultdict
d = defaultdict(list)
d['key'].append('mykey')

Dies ist etwas effizienter, als setdefaultwenn Sie am Ende keine neuen Listen erstellen, die Sie am Ende nicht verwenden. Bei jedem Aufruf von setdefaultwird eine neue Liste erstellt, auch wenn das Element bereits im Wörterbuch vorhanden ist.

Nathan Villaescusa
quelle
14

Sie können defaultdict in verwenden collections.

Ein Beispiel aus doc:

s = [('yellow', 1), ('blue', 2), ('yellow', 3), ('blue', 4), ('red', 1)]
d = defaultdict(list)
for k, v in s:
    d[k].append(v)
iMom0
quelle
0
dictionary['key'] = dictionary.get('key', []) + list_to_append
Tomas Silva Ebensperger
quelle
1
Sie sollten den (sehr geringen) Vorteil erklären, den dies bei bestimmten Ausnahmen hat. Als reiner Code ist nicht klar, warum die zusätzliche Antwort benötigt wird.
Davis Herring
Hallo, nur eine Alternative ohne zusätzliche Importe. Dies kann eindeutig mit einer if-Anweisung erfolgen. Ich schlage nur eine Alternative vor, bei der die Leistung von .get () anstelle von dict [] verwendet wird.
Tomas Silva Ebensperger
In den beiden oberen Antworten werden zwei verschiedene Arten ohne Importe erwähnt (wenn auch nicht dict.get).
Davis Herring