Étant donné un dictionnaire que { k1: v1, k2: v2 ... }
je veux obtenir, { k1: f(v1), k2: f(v2) ... }
je passe une fonction f
.
Existe-t-il une telle fonction intégrée? Ou dois-je faire
dict([(k, f(v)) for (k, v) in my_dictionary.iteritems()])
Idéalement, j'écrirais
my_dictionary.map_values(f)
ou
my_dictionary.mutate_values_with(f)
Autrement dit, peu importe que le dictionnaire d'origine soit muté ou qu'une copie soit créée.
python
dictionary
map-function
Tarrasch
la source
la source
dict((k, f(v)) for k, v in mydict.iteritems())
, c'est-à-dire sans les crochets, d'empêcher la création d'une liste intermédiaire via un générateur.Réponses:
Il n'y a pas une telle fonction; la façon la plus simple de le faire est d'utiliser une compréhension dict:
En python 2.7, utilisez la
.iteritems()
méthode au lieu de.items()
pour économiser de la mémoire. La syntaxe de compréhension de dict n'a pas été introduite avant Python 2.7.Notez qu'il n'y a pas non plus une telle méthode sur les listes; il faudrait utiliser une compréhension de liste ou la
map()
fonction.En tant que tel, vous pouvez également utiliser la
map()
fonction pour traiter votre dict:mais ce n'est pas vraiment lisible.
la source
dict(zip(a, map(f, a.values())))
est légèrement plus court, mais je dois penser à ce qu'il fait et me rappeler que oui, les clés et les valeurs sont itérées dans le même ordre si le dict ne change pas. Je n'ai pas du tout à penser à ce que fait le dictcomp, et c'est donc la bonne réponse.my_dictionary.__getitem__
appels de nombre de clés .lambda (k,v): (k, f(v))
doit être réécrit dans quelque chose commelambda k_v: (k_v[0], f(k_v[1]))
Ces outils sont parfaits pour ce type de logique simple mais répétitive.
http://toolz.readthedocs.org/en/latest/api.html#toolz.dicttoolz.valmap
Vous amène là où vous voulez être.
la source
Vous pouvez le faire sur place, plutôt que de créer un nouveau dict, ce qui peut être préférable pour les grands dictionnaires (si vous n'avez pas besoin d'une copie).
résulte en
my_dictionary
contenant:la source
mapdict
àmutate_values_with
ou quelque chose pour le rendre clair que vous réécrivez le dict! :)zip(d.keys(), d.values())
fonctionne pour plus de versions au lieu deiteritems()
{k:f(v) for k,v in iter(d.items())}
En raison de PEP-0469 qui a renommé iteritems () en items () et PEP-3113 qui a supprimé le décompactage des paramètres Tuple , dans Python 3.x, vous devriez écrire Martijn Pieters ♦ répondre comme ceci:
la source
Bien que ma réponse d'origine ait manqué le point (en essayant de résoudre ce problème avec la solution de la clé d'accès dans l'usine de defaultdict ), je l'ai retravaillée pour proposer une solution réelle à la présente question.
C'est ici:
Usage:
L'idée est de sous-classer le dict original pour lui donner la fonctionnalité souhaitée: "mapper" une fonction sur toutes les valeurs.
Le point positif est que ce dictionnaire peut être utilisé pour stocker les données d'origine comme s'il s'agissait d'un
dict
, tout en transformant toutes les données sur demande avec un rappel.Bien sûr, n'hésitez pas à nommer la classe et la fonction comme vous le souhaitez (le nom choisi dans cette réponse est inspiré par la
array_walk()
fonction de PHP ).Remarque: Ni le bloc
try
-except
ni lesreturn
instructions ne sont obligatoires pour la fonctionnalité, ils sont là pour imiter davantage le comportement des PHParray_walk
.la source
__missing__
méthode ne sera pas appelée pour les clés existantes, que nous voulons transformer, sauf si la méthode d'usine passée utilise le dict d'origine comme une solution de repli, mais comme cela ne fait pas partie de l'exemple d'utilisation, Je considère que c'est une réponse insatisfaisante au problème actuel.Given a dictionary { k1: v1, k2: v2 ... } ...
. Autrement dit, vous avez déjà undict
pour commencer ..{v1: f(v1), v2: f(v2), ...}
donné[v1, v2, ...]
, et non donné un dict. Je vais modifier ma réponse pour corriger cela.Pour éviter de faire de l'indexation à l'intérieur de lambda, comme:
Vous pouvez également faire:
la source
lambda(k,v)
, ne fonctionnera pas. Voir stackoverflow.com/questions/21892989/…Je viens juste de traverser ce cas d'utilisation. J'ai implémenté la réponse de gens , en ajoutant une approche récursive pour gérer les valeurs qui sont également des dict:
Cela peut être utile lorsque vous traitez des fichiers json ou yaml qui codent des chaînes en octets dans Python 2
la source