cómo convertir la lista de dict a dict

5 minutos de lectura

avatar de usuario de sush
susurro

Cómo convertir la lista de dict a dict. A continuación se muestra la lista de dict

data = [{'name': 'John Doe', 'age': 37, 'sex': 'M'},
        {'name': 'Lisa Simpson', 'age': 17, 'sex': 'F'},
        {'name': 'Bill Clinton', 'age': 57, 'sex': 'M'}]

a

data = {'John Doe': {'name': 'John Doe', 'age': 37, 'sex': 'M'},
        'Lisa Simpson': {'name': 'Lisa Simpson', 'age': 17, 'sex': 'F'},
        'Bill Clinton': {'name': 'Bill Clinton', 'age': 57, 'sex': 'M'}}

  • Intente poner su segunda línea en un script de Python y ejecútelo. ¿Funcionará correctamente? No me parece…

    – Platino Azur

    8 de marzo de 2011 a las 17:52

  • Su pregunta realmente no tiene sentido tal como se publicó. ¿Cuáles desea que sean las claves y los valores asociados de su dictado resultante? Lo segundo que escribiste no es un objeto de Python válido.

    – dfan

    8 de marzo de 2011 a las 17:53

  • docs.python.org/tutorial/datastructures.html#dictionaries

    – Ignacio Vázquez-Abrams

    8 de marzo de 2011 a las 17:54

  • lo que quería como salida no es un diccionario, ¡sino un conjunto! editar la pregunta tal vez para evitar confusiones

    – Gavin

    27 de octubre de 2018 a las 12:03


avatar de usuario de joaquín
joaquín

Una posible solución usando nombres como las nuevas claves:

new_dict = {}
for item in data:
   name = item['name']
   new_dict[name] = item

Con python 3.x también puede usar comprensiones de dictado para el mismo enfoque de una manera más agradable:

new_dict = {item['name']:item for item in data}

Como se sugiere en un comentario de Paul McGuire, si no desea el nombre en el dictado interno, puede hacerlo:

new_dict = {}
for item in data:
   name = item.pop('name')
   new_dict[name] = item

  • Eso dejará un campo de nombre adicional, que puede o no ser lo que el usuario quiere. (es decir, el nuevo diccionario parece {'Lisa Simpson': {'name': 'Lisa Simpson', 'age': 17, 'sex': 'F'} ...})

    – Platino Azur

    8 de marzo de 2011 a las 18:04


  • agregue “item.pop(‘name’)” después de asignar el nombre, y luego no obtendrá el campo de nombre adicional.

    – PaulMcG

    8 de marzo de 2011 a las 18:09

  • @Platinum: eso es bastante común cuando se usa un diccionario como tabla de búsqueda. Otra estructura de datos puede hacer referencia al valor del diccionario directamente sin perder la clave (en lugar de almacenar la clave y buscarla en la tabla cada vez que se accede a ella).

    – Ben en blanco

    8 de marzo de 2011 a las 18:11

  • @Platinum Azure: tienes razón, pero la pregunta OP no da ninguna pista al respecto. Esta es solo una solución posible. He usado dictados similares (uso de campos redundantes) en algunas aplicaciones cuando quiero obtener la información completa de un tema usando un valor en la información del tema. Obviamente, también se podrían usar otras claves primarias o, como se sugiere, eliminar la clave redundante del dict original.

    – joaquín

    8 de marzo de 2011 a las 18:18


  • ¿Qué pasa si el data es dinámico y no es fijo name ¿llave? ¿Hay alguna manera de resolver eso? Estoy enfrentando un problema similar solo que en mi caso el data consta de consultas MongoDB, por lo que no es estático.

    usuario5512021

    8 de marzo de 2019 a las 14:17

Avatar de usuario de Vlad Bezden
Vlad Bezden

Con python 3.3 y superior, puede utilizar CadenaMapa

Un ChainMap agrupa varios dictados u otras asignaciones para crear una vista única y actualizable. Si no se especifican mapas, se proporciona un solo diccionario vacío para que una nueva cadena siempre tenga al menos un mapa.

from collections import ChainMap

data = dict(ChainMap(*data))

  • Este es el camino a seguir.

    – Yaakov Bressler

    9 de febrero de 2021 a las 20:36

  • Elegante. Buena respuesta

    – Orestis Zekai

    13 de abril de 2021 a las 9:25

  • ¿Se garantiza que esto sea más rápido? Las respuestas anteriores iteran en toda la lista, por lo que es O (n), ¿ChainMap es menor que esto?

    – gudé

    1 ago 2021 a las 20:45

  • está devolviendo solo la primera entrada de la fila como dict.

    – Abdul Haseeb

    15/09/2021 a las 20:19

avatar de usuario de phynfo
phynfo

Si los dictados no comparten la clave, entonces podría usar:

dict((key,d[key]) for d in data for key in d)

¿Probablemente sea mejor en su caso generar un dict con listas como valores?

newdict={}
for k,v in [(key,d[key]) for d in data for key in d]:
  if k not in newdict: newdict[k]=[v]
  else: newdict[k].append(v)

Esto produce:

>>> newdict
`{'age': [37, 17, 57], 'name': ['John Doe', 'Lisa Simpson', 'Bill Clinton'], 'sex': ['M', 'F', 'M']}`

Avatar de usuario de ANK
ANK

Pruebe este enfoque:

dict((key, val) for k in data for key, val in k.items())

Avatar de usuario de MrFrosty
señorescarchado

No compliquemos esto:

simple_dictionary = dict(data[0])

  • no es la solución, pero ayudó en mi pregunta, así que estoy votando esto

    – Dragón picante

    15 oct 2020 a las 22:16

Avatar de usuario de la comunidad
Comunidad

¿Quizás quieres que el nombre sea la clave? Realmente no especifica, ya que su segundo ejemplo no es válido y no es realmente significativo.

Tenga en cuenta que mi ejemplo elimina la clave “nombre” del valor, lo que puede ser deseable (o quizás no).

data = [{'name': 'John Doe', 'age': 37, 'sex': 'M'},
        {'name': 'Lisa Simpson', 'age': 17, 'sex': 'F'},
        {'name': 'Bill Clinton', 'age': 57, 'sex': 'M'}]
newdata = {}
for entry in data:
    name = entry.pop('name') #remove and return the name field to use as a key
    newdata[name] = entry
print newdata
##{'Bill Clinton': {'age': 57, 'sex': 'M'},
## 'John Doe': {'age': 37, 'sex': 'M'},
## 'Lisa Simpson': {'age': 17, 'sex': 'F'}}
print newdata['John Doe']['age']
## 37

  • no es la solución, pero ayudó en mi pregunta, así que estoy votando esto

    – Dragón picante

    15 oct 2020 a las 22:16

avatar de usuario de mcstarioni
mcstarioni

Mis 5 centavos, no me gustó ninguna de las respuestas:

from functools import reduce
collection = [{'hello': 1}, {'world': 2}]
answer = reduce(lambda aggr, new: aggr.update(new) or aggr, collection, {})

¿Ha sido útil esta solución?