Convierte una cadena JSON a dict usando Python

415

Estoy un poco confundido con JSON en Python. Para mí, parece un diccionario, y por eso estoy tratando de hacer eso:

{
    "glossary":
    {
        "title": "example glossary",
        "GlossDiv":
        {
            "title": "S",
            "GlossList":
            {
                "GlossEntry":
                {
                    "ID": "SGML",
                    "SortAs": "SGML",
                    "GlossTerm": "Standard Generalized Markup Language",
                    "Acronym": "SGML",
                    "Abbrev": "ISO 8879:1986",
                    "GlossDef":
                    {
                        "para": "A meta-markup language, used to create markup languages such as DocBook.",
                        "GlossSeeAlso": ["GML", "XML"]
                    },
                    "GlossSee": "markup"
                }
            }
        }
    }
}

Pero cuando lo hago print dict(json), da un error.

¿Cómo puedo transformar esta cadena en una estructura y luego llamar json["title"]para obtener un "glosario de ejemplo"?

Frias
fuente

Respuestas:

756

json.loads()

import json

d = json.loads(j)
print d['glossary']['title']
Ignacio Vazquez-Abrams
fuente
99
¿Cuál es la diferencia entre json.load y json.loads?
Shivam Agrawal
55
@ ShivamAgrawal: exactamente lo que dice en la lata .
Ignacio Vázquez-Abrams
64
@ShivamAgrawal: la diferencia es que .load()analiza un objeto de archivo; .loads()analiza un objeto string / unicode.
fyngyrz
1
Me molesta que el autor de esta función no haya escrito una función contenedora para realizar una verificación de tipo en los datos que se pasan para elegir automáticamente la función correcta para llamar. Tampoco me gusta la vaga nomenclatura utilizada. Esto es lo que escribí para combatir esto: def read_json(json_data): if (type(json_data) == str): return json.loads(json_data) elif (str(type(json_data)) == "<class '_io.TextIOWrapper'>"): return json.load(json_data) estoy seguro de que esto se puede mejorar, pero ahora puedes invocar d = read_json(j)un json 'str' o 'file'.
Jacques Mathieu
2
@JacquesMathieu, Hola Jacques, gracias por tu función, hice una pequeña mejora, ya que a veces uso diccionarios: def read_json (json_data): if (type (json_data) == str): # Para cadenas, devuelve json.loads (json_data) elif (str (type (json_data)) == "<class '_io.TextIOWrapper'>"): #Para los archivos devuelven json.load (json_data) elif (type (json_data) == dict): # Para los diccionarios devuelven json.loads (json.dumps (json_data))
Gabriel Aizcorbe
98

Cuando comencé a usar json, estaba confundido e incapaz de resolverlo por algún tiempo, pero finalmente obtuve lo que quería
Aquí está la solución simple

import json
m = {'id': 2, 'name': 'hussain'}
n = json.dumps(m)
o = json.loads(n)
print(o['id'], o['name'])
Hussain
fuente
¿Por qué estás volcados (m) primero?
Han Van Pham
Lo usé para demostrar la serialización y la deserialización. Usar loads(..)on '{"id": 2, "name": "hussain"}'también debería estar bien, como la respuesta aceptada.
Hussain
1
volcados y cargas funciona perfecto para mí, mientras que la respuesta aceptada no es, muchas gracias @Hussain por salvarme un time, para su información, estoy tratando loadsde cadenas dinámicas con codificación utf-8 ...
Mohammed Sufian
19

use simplejson o cjson para acelerar

import simplejson as json

json.loads(obj)

or 

cjson.decode(obj)
locojay
fuente
16

Si confía en la fuente de datos, puede usar evalpara convertir su cadena en un diccionario:

eval(your_json_format_string)

Ejemplo:

>>> x = "{'a' : 1, 'b' : True, 'c' : 'C'}"
>>> y = eval(x)

>>> print x
{'a' : 1, 'b' : True, 'c' : 'C'}
>>> print y
{'a': 1, 'c': 'C', 'b': True}

>>> print type(x), type(y)
<type 'str'> <type 'dict'>

>>> print y['a'], type(y['a'])
1 <type 'int'>

>>> print y['a'], type(y['b'])
1 <type 'bool'>

>>> print y['a'], type(y['c'])
1 <type 'str'>
kakhkAtion
fuente
1
La cadena en su ejemplo no es JSON.
bfontaine
1
Cierto. Se evalúa en un diccionario, que se puede cargar / volcar fácilmente como JSON (y, por supuesto, es posible que necesite una función de codificador json personalizada si su diccionario no tiene valores json).
kakhkAtion
3
No. Debe Nunca evaluar los datos de entrada como un código. Este puede ser su pequeño proyecto favorito que utiliza datos en los que confía, pero el código incorrecto puede reutilizarse y las malas prácticas repetirse en proyectos reales, dejando un gran código de seguridad.
NetworkMeister el
¡Y es por eso que mi respuesta comienza con "si confías en la fuente de datos"! Pero es cierto, esto es más un truco, y definitivamente no es la mejor práctica.
kakhkAtion
Puede confiar totalmente en la fuente de datos si es la suya. Esto es realmente útil para convertir un objeto JS stringified en un dic en una cadena JSON adecuada.
Vadorequest