funciones - ejercicio diccionario python
"Aplanar" una lista de diccionarios (9)
Enfoque
Use reduce para aplicar cada dictado a un inicializador vacío. Dado que dict.update
siempre devuelve None
, use d.update(src) or d
para reduce
el valor de retorno deseado.
Código
final_dict = reduce(lambda d, src: d.update(src) or d, dicts, {})
Prueba
>>> dicts = [{''a'': 1, ''b'': 2}, {''b'': 3, ''c'': 4}, {''a'': 6}]
>>> final_dict = reduce(lambda d, src: d.update(src) or d, dicts, {})
>>> final_dict
{''a'': 6, ''c'': 4, ''b'': 3}
Así que mi objetivo es ir desde:
fruitColourMapping = [{''apple'': ''red''}, {''banana'': ''yellow''}]
a
finalMap = {''apple'': ''red'', ''banana'': ''yellow''}
Una forma que tengo es:
from itertools import chain
fruits = list(chain.from_iterable([d.keys() for d in fruitColourMapping]))
colour = list(chain.from_iterable([d.values() for d in fruitColourMapping]))
return dict(zip(fruits, colour))
¿Hay alguna mejor manera más pitónica?
¿Por qué copiar en absoluto?
En Python 3, puedes usar el nuevo ChainMap
:
Un ChainMap agrupa varios dicts (u otras asignaciones) para crear una vista única y actualizable.
Las asignaciones subyacentes se almacenan en una lista. Esa lista es pública y se puede acceder o actualizar usando el atributo de mapas . No hay otro estado. Las búsquedas buscan sucesivamente las asignaciones subyacentes hasta que se encuentra una clave. Por el contrario, las escrituras, actualizaciones y eliminaciones solo funcionan en la primera asignación.
Todo lo que necesita es esto (cambie los nombres para cumplir con las convenciones de nomenclatura de Python ):
from collections import ChainMap
fruit_colour_mapping = [{''apple'': ''red''}, {''banana'': ''yellow''}]
final_map = ChainMap(*fruit_colour_mapping)
Y luego puedes usar todas las operaciones de mapeo normales:
# print key value pairs:
for element in final_map.items():
print(element)
# change a value:
final_map[''banana''] = ''green'' # supermarkets these days....
# access by key:
print(final_map[''banana''])
¿Por qué no desempaquetar, python 3.5 arriba?
a, b = [{''apple'': ''red''}, {''banana'': ''yellow''}]
print(dict(a,**b))
Ahora tienes:
{''apple'': ''red'', ''banana'': ''yellow''}
Para la salida.
En Python 3.5, se introdujo el desempaque del diccionario (ver PEP 448 ):
a, b = [{''apple'': ''red''}, {''banana'': ''yellow''}]
{**a, **b}
# {''apple'': ''red'', ''banana'': ''yellow''}
En lugar de deconstruir y reconstruir, simplemente copie y actualice:
final_map = {}
for fruit_color_definition in fruit_color_mapping:
final_map.update(fruit_color_definition)
También puedes probar:
finalMap = dict(item for mapping in fruitColourMapping for item in mapping.items())
dict(d.items()[0] for d in fruitColourMapping)
finalMap = {}
for d in fruitColourMapping:
finalMap.update(d)
{k: v for d in fruitColourMapping for k, v in d.items()}