Biorąc pod uwagę słownik, { k1: v1, k2: v2 ... }
który chcę uzyskać, { k1: f(v1), k2: f(v2) ... }
pod warunkiem, że podam funkcję f
.
Czy jest taka wbudowana funkcja? Czy muszę to zrobić
dict([(k, f(v)) for (k, v) in my_dictionary.iteritems()])
Idealnie po prostu bym napisał
my_dictionary.map_values(f)
lub
my_dictionary.mutate_values_with(f)
Oznacza to, że nie ma dla mnie znaczenia, czy oryginalny słownik jest zmutowany, czy tworzona jest kopia.
python
dictionary
map-function
Tarrasch
źródło
źródło
dict((k, f(v)) for k, v in mydict.iteritems())
, tj. Bez nawiasów kwadratowych, które uniemożliwiłyby utworzenie listy pośredniej za pomocą generatora.Odpowiedzi:
Nie ma takiej funkcji; najłatwiej to zrobić, używając rozumienia dykta:
W Pythonie 2.7 użyj
.iteritems()
metody zamiast.items()
oszczędzania pamięci. Składnia rozumienia dict została wprowadzona dopiero w Pythonie 2.7.Zauważ, że nie ma takiej metody na listach; musiałbyś użyć rozumienia listy lub
map()
funkcji.Jako taki, możesz również użyć
map()
funkcji do przetworzenia swojego nagrania:ale tak naprawdę nie jest to tak czytelne.
źródło
dict(zip(a, map(f, a.values())))
jest nieznacznie krótszy, ale muszę pomyśleć o tym, co robi i przypomnieć sobie, że tak, klucze i wartości są iterowane w tej samej kolejności, jeśli dyktand się nie zmienia. Nie muszę wcale myśleć o tym, co robi dictcomp, więc jest to właściwa odpowiedź.my_dictionary.__getitem__
połączeń razy razy .lambda (k,v): (k, f(v))
należy przepisać na coś w stylulambda k_v: (k_v[0], f(k_v[1]))
Te narzędzia są idealne do tego rodzaju prostej, ale powtarzalnej logiki.
http://toolz.readthedocs.org/en/latest/api.html#toolz.dicttoolz.valmap
Daje ci dokładnie to, gdzie chcesz być.
źródło
Możesz to zrobić w miejscu, zamiast tworzyć nowy słownik, co może być lepsze w przypadku dużych słowników (jeśli nie potrzebujesz kopii).
skutkuje
my_dictionary
zawartością:źródło
mapdict
namutate_values_with
lub coś zrobić to jasne, że pan przepisać dict! :)zip(d.keys(), d.values())
działa dla większej liczby wersji zamiastiteritems()
{k:f(v) for k,v in iter(d.items())}
Ze względu na PEP-0469, który zmienił nazwę iteritems () na items () i PEP-3113, który usunął rozpakowywanie parametrów Tuple , w Pythonie 3.x powinieneś napisać Martijn Pieters ♦ odpowiedz w ten sposób:
źródło
Chociaż moja pierwotna odpowiedź nie trafiła w sedno (próbując rozwiązać ten problem z rozwiązaniem klucza dostępu w fabryce defaultdict ), przerobiłem go, aby zaproponować faktyczne rozwiązanie obecnego pytania.
Oto on:
Stosowanie:
Chodzi o podklasę oryginalnego słownika, aby zapewnić mu pożądaną funkcjonalność: „mapowanie” funkcji na wszystkie wartości.
Plusem jest to, że słownik ten może być używany do przechowywania oryginalnych danych, tak jakby to był
dict
, podczas przekształcania dowolnych danych na żądanie za pomocą wywołania zwrotnego.Oczywiście możesz nazwać klasę i funkcję tak, jak chcesz (nazwa wybrana w tej odpowiedzi jest inspirowana
array_walk()
funkcją PHP ).Uwaga: Ani
try
-except
blok anireturn
stwierdzenia są obowiązkowe dla funkcjonalności, są tam do dalszego naśladować zachowanie PHParray_walk
.źródło
__missing__
metoda nie będzie wywoływana dla istniejących kluczy, które chcemy przekształcić, chyba że metoda fabryczna, która przeszła, używa w jakiś sposób dyktowania źródłowego jako rezerwowego, ale ponieważ nie jest to część przykładowego użycia, Uważam to za niezadowalającą odpowiedź na bieżący problem.Given a dictionary { k1: v1, k2: v2 ... } ...
. To znaczy, musisz jużdict
zacząć ...{v1: f(v1), v2: f(v2), ...}
danego[v1, v2, ...]
, a nie dyktowania. Zmienię swoją odpowiedź, aby to poprawić.Aby uniknąć indeksowania od wewnątrz lambda, na przykład:
Możesz także:
źródło
lambda(k,v)
nie będzie działać. Zobacz stackoverflow.com/questions/21892989/...Właśnie natknąłem się na ten przypadek użycia. Zaimplementowałem odpowiedź gensa , dodając rekurencyjne podejście do obsługi wartości, które również dyktują:
Może to być przydatne w przypadku plików json lub yaml, które kodują ciągi jako bajty w Pythonie 2
źródło