Wenn { k1: v1, k2: v2 ... }
ich ein Wörterbuch habe, das ich erhalten möchte, übergebe { k1: f(v1), k2: f(v2) ... }
ich eine Funktion f
.
Gibt es eine solche eingebaute Funktion? Oder muss ich tun
dict([(k, f(v)) for (k, v) in my_dictionary.iteritems()])
Im Idealfall würde ich einfach schreiben
my_dictionary.map_values(f)
oder
my_dictionary.mutate_values_with(f)
Das heißt, es ist mir egal, ob das ursprüngliche Wörterbuch mutiert oder eine Kopie erstellt wird.
python
dictionary
map-function
Tarrasch
quelle
quelle
dict((k, f(v)) for k, v in mydict.iteritems())
, ohne die eckigen Klammern, die Erstellung einer Zwischenliste über einen Generator zu verhindern.Antworten:
Es gibt keine solche Funktion; Der einfachste Weg, dies zu tun, besteht darin, ein Diktatverständnis zu verwenden:
Verwenden Sie in Python 2.7 die
.iteritems()
Methode.items()
, um Speicherplatz zu sparen. Die Diktatverständnis-Syntax wurde erst in Python 2.7 eingeführt.Beachten Sie, dass es in Listen auch keine solche Methode gibt. Sie müssten ein Listenverständnis oder die
map()
Funktion verwenden.Daher können Sie die
map()
Funktion auch zur Verarbeitung Ihres Diktats verwenden:aber das ist wirklich nicht so lesbar.
quelle
dict(zip(a, map(f, a.values())))
ist geringfügig kürzer, aber ich muss darüber nachdenken, was es tut, und mich daran erinnern, dass Schlüssel und Werte in derselben Reihenfolge wiederholt werden, wenn sich das Diktat nicht ändert. Ich muss überhaupt nicht darüber nachdenken, was der Diktiercomputer tut, und deshalb ist es die richtige Antwort.my_dictionary.__getitem__
Anrufe verwenden.lambda (k,v): (k, f(v))
lambda k_v: (k_v[0], f(k_v[1]))
Diese Tools eignen sich hervorragend für diese Art von einfacher, aber sich wiederholender Logik.
http://toolz.readthedocs.org/en/latest/api.html#toolz.dicttoolz.valmap
Bringt Sie genau dahin, wo Sie sein möchten.
quelle
Sie können dies direkt tun, anstatt ein neues Diktat zu erstellen, was für große Wörterbücher vorzuziehen ist (wenn Sie keine Kopie benötigen).
führt zu folgenden
my_dictionary
:quelle
mapdict
zumutate_values_with
oder etwas , um es Kristall deutlich zu machen , dass Sie die dict umschreiben! :)zip(d.keys(), d.values())
funktioniert für mehr Versionen anstelle voniteritems()
{k:f(v) for k,v in iter(d.items())}
Aufgrund von PEP-0469, das iteritems () in items () umbenannte, und PEP-3113, das das Entpacken von Tuple-Parametern entfernte , sollten Sie in Python 3.x Martijn Pieters ♦ Antwort wie folgt schreiben :
quelle
Während meine ursprüngliche Antwort den Punkt verfehlt hat (indem ich versucht habe, dieses Problem mit der Lösung für den Zugriff auf den Schlüssel in der Factory of DefaultDict zu lösen ), habe ich sie überarbeitet, um eine tatsächliche Lösung für die vorliegende Frage vorzuschlagen.
Hier ist es:
Verwendung:
Die Idee ist, das ursprüngliche Diktat in Unterklassen zu unterteilen, um ihm die gewünschte Funktionalität zu geben: eine Funktion über alle Werte "abzubilden".
Der Pluspunkt ist, dass dieses Wörterbuch verwendet werden kann, um die Originaldaten so zu speichern, als ob es eine wäre
dict
, während alle Daten auf Anfrage mit einem Rückruf transformiert werden.Natürlich können Sie die Klasse und die Funktion beliebig benennen (der in dieser Antwort gewählte Name ist von der PHP-
array_walk()
Funktion inspiriert ).Hinweis: Weder der
try
-except
Block noch diereturn
Anweisungen sind für die Funktionalität obligatorisch, sie dienen dazu, das Verhalten der PHPs weiter nachzuahmenarray_walk
.quelle
__missing__
Methode nicht für vorhandene Schlüssel aufgerufen wird, die wir transformieren möchten, es sei denn, die übergebene Factory-Methode verwendet das Ursprungsdiktat irgendwie als Fallback, aber da dies nicht Teil der Beispielverwendung ist, Ich halte dies für eine unbefriedigende Antwort auf das vorliegende Problem.Given a dictionary { k1: v1, k2: v2 ... } ...
. Das heißt, Sie haben bereits einedict
zu Beginn ..{v1: f(v1), v2: f(v2), ...}
gegeben zu werden[v1, v2, ...]
, und kein Diktat gegeben. Ich werde meine Antwort bearbeiten, um das zu korrigieren.Um eine Indizierung innerhalb von Lambda zu vermeiden, gehen Sie wie folgt vor:
Sie können auch tun:
quelle
lambda(k,v)
funktioniert es nicht. Siehe stackoverflow.com/questions/21892989/…Gerade über diesen Anwendungsfall gekommen. Ich habe die Antwort von gens implementiert und einen rekursiven Ansatz für den Umgang mit Werten hinzugefügt, die auch Diktate sind:
Dies kann nützlich sein, wenn Sie mit JSON- oder YamL-Dateien arbeiten, die Zeichenfolgen in Python 2 als Bytes codieren
quelle