Dado un diccionario { k1: v1, k2: v2 ... }
que quiero obtener { k1: f(v1), k2: f(v2) ... }
siempre que pase una función f
.
¿Existe alguna función incorporada? O tengo que hacer
dict([(k, f(v)) for (k, v) in my_dictionary.iteritems()])
Lo ideal sería escribir
my_dictionary.map_values(f)
o
my_dictionary.mutate_values_with(f)
Es decir, no me importa si el diccionario original está mutado o si se crea una copia.
python
dictionary
map-function
Tarrasch
fuente
fuente
dict((k, f(v)) for k, v in mydict.iteritems())
, es decir, sin los corchetes, que evitaría la creación de una lista intermedia a través de un generador.Respuestas:
No hay tal función; La forma más fácil de hacer esto es usar una comprensión dict:
En python 2.7, use el
.iteritems()
método en lugar de.items()
guardar memoria. La sintaxis de comprensión dict no se introdujo hasta Python 2.7.Tenga en cuenta que tampoco existe tal método en las listas; tendrías que usar una lista de comprensión o la
map()
función.Como tal, también podría usar la
map()
función para procesar su dict:pero eso no es tan legible, de verdad.
fuente
dict(zip(a, map(f, a.values())))
es marginalmente más corto, pero tengo que pensar en lo que está haciendo y recordarme que sí, las claves y los valores se repiten en el mismo orden si el dict no cambia. No tengo que pensar en absoluto sobre lo que está haciendo el dictcomp, por lo que es la respuesta correcta.my_dictionary.__getitem__
llamadas de número de claves .lambda (k,v): (k, f(v))
debe reescribirse en algo comolambda k_v: (k_v[0], f(k_v[1]))
Estas herramientas son excelentes para este tipo de lógica simple pero repetitiva.
http://toolz.readthedocs.org/en/latest/api.html#toolz.dicttoolz.valmap
Te lleva justo donde quieres estar.
fuente
Puede hacer esto en el lugar, en lugar de crear un nuevo dict, que puede ser preferible para diccionarios grandes (si no necesita una copia).
resulta en
my_dictionary
contener:fuente
mapdict
demutate_values_with
o algo para dejar muy claro que reescribir el dict! :)zip(d.keys(), d.values())
funciona para más versiones en lugar deiteritems()
{k:f(v) for k,v in iter(d.items())}
Debido a PEP-0469 que renombró iteritems () a items () y PEP-3113 que eliminó el desempaquetado de parámetros Tuple , en Python 3.x debería escribir Martijn Pieters ♦ responda así:
fuente
Si bien mi respuesta original perdió el punto (al tratar de resolver este problema con la solución para acceder a la clave en la fábrica de defaultdict ), la modifiqué para proponer una solución real a la presente pregunta.
Aquí está:
Uso:
La idea es subclasificar el dict original para darle la funcionalidad deseada: "mapear" una función sobre todos los valores.
El punto a favor es que este diccionario se puede usar para almacenar los datos originales como si fuera un
dict
, mientras se transforma cualquier dato a pedido con una devolución de llamada.Por supuesto, siéntase libre de nombrar la clase y la función de la manera que desee (el nombre elegido en esta respuesta está inspirado en la
array_walk()
función de PHP ).Nota: Ni el bloque
try
-except
ni lasreturn
declaraciones son obligatorias para la funcionalidad, están ahí para imitar aún más el comportamiento de los PHParray_walk
.fuente
__missing__
método no se llamará para las claves existentes, que queremos transformar, a menos que el método de fábrica aprobado utilice el dict de origen como una alternativa, pero como eso no es parte del uso del ejemplo, Considero que esta es una respuesta insatisfactoria al problema en cuestión.Given a dictionary { k1: v1, k2: v2 ... } ...
. Es decir, ya tienes unadict
para empezar ...{v1: f(v1), v2: f(v2), ...}
dado[v1, v2, ...]
, y no un dictamen. Editaré mi respuesta para corregir eso.Para evitar la indexación desde el interior de lambda, como:
También puedes hacer:
fuente
lambda(k,v)
lo tanto , no funcionará. Ver stackoverflow.com/questions/21892989/…Acabo de encontrar este caso de uso. Implementé la respuesta de gens , agregando un enfoque recursivo para manejar valores que también son dictados:
Esto puede ser útil cuando se trata de archivos json o yaml que codifican cadenas como bytes en Python 2
fuente