Converter string JSON em dict usando Python

415

Estou um pouco confuso com JSON em Python. Para mim, parece um dicionário e, por esse motivo, estou tentando fazer isso:

{
    "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"
                }
            }
        }
    }
}

Mas quando eu faço print dict(json), dá um erro.

Como posso transformar essa string em uma estrutura e depois chamar json["title"]para obter o "glossário de exemplo"?

Frias
fonte

Respostas:

756

json.loads()

import json

d = json.loads(j)
print d['glossary']['title']
Ignacio Vazquez-Abrams
fonte
9
Qual é a diferença entre json.load e json.loads?
Shivam Agrawal
5
@ShivamAgrawal: Exatamente o que diz na lata .
Ignacio Vazquez-Abrams
64
@ShivamAgrawal: A diferença é que .load()analisa um objeto de arquivo; .loads()analisa um objeto string / unicode.
Fyngyrz
1
Incomoda-me que o autor desta função não tenha gravado uma função de invólucro para executar uma verificação de tipo nos dados transmitidos para escolher automaticamente a função correta a ser chamada. Eu também não gosto da nomenclatura vaga usada. Aqui está o que escrevi para combater isso: 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) Tenho certeza de que isso pode ser melhorado, mas agora você pode chamar d = read_json(j)um json 'str' ou 'file'.
Jacques Mathieu
2
@JacquesMathieu, Oi Jacques, obrigado pela sua função, fiz uma pequena melhoria, pois às vezes uso dicionários: def read_json (json_data): if (type (json_data) == str): # Para strings, retorne json.loads (json_data) elif (str (type (json_data)) == "<class '_io.TextIOWrapper'>"): #Para os arquivos retornarem json.load (json_data) elif (type (json_data) == dict): # Para os dicionários, retorne json.loads (json.dumps (json_data))
Gabriel Aizcorbe
98

Quando comecei a usar o json, fiquei confuso e incapaz de descobrir por algum tempo, mas finalmente consegui o que queria.
Aqui está a solução simples

import json
m = {'id': 2, 'name': 'hussain'}
n = json.dumps(m)
o = json.loads(n)
print(o['id'], o['name'])
Hussain
fonte
Por que você está despejando (m) primeiro?
Han Van Pham
Eu o usei para demonstrar serialização e desserialização. Usar loads(..)on '{"id": 2, "name": "hussain"}'também deve ser bom como a resposta aceita.
Hussain
1
despejos e cargas funciona perfeito para mim, enquanto a resposta aceita não é, muito obrigado @Hussain por me salvar de um timeFYI, estou tentando loadspartir de strings dinâmicas com codificação utf-8 ...
Mohammed Sufian
19

use simplejson ou cjson para acelerações

import simplejson as json

json.loads(obj)

or 

cjson.decode(obj)
locojay
fonte
16

Se você confia na fonte de dados, pode evalconverter sua string em um dicionário:

eval(your_json_format_string)

Exemplo:

>>> 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
fonte
1
A sequência no seu exemplo não é JSON.
precisa saber é o seguinte
1
Verdade. Ele é comparado a um dicionário, que pode ser facilmente carregado / despejado como JSON (e, é claro, você pode precisar de uma função de codificador json personalizada se o seu dicionário não possuir valores json).
precisa saber é o seguinte
3
Não. Você nunca deve avaliar os dados de entrada como um código. Esse pode ser o seu pequeno projeto de estimação que usa dados confiáveis, mas códigos ruins podem ser reutilizados e práticas ruins repetidas em projetos reais, deixando um grande código de segurança.
NetworkMeister
E é por isso que minha resposta começa com "se você confia na fonte de dados"! Mas é verdade, isso é mais um truque e definitivamente não é a melhor prática.
kakhkAtion
Você pode confiar totalmente na fonte de dados, se for sua. Isso é realmente útil para converter um objeto JS stringified em um dic em uma string JSON apropriada.
Vadorequest 6/03/19