Convertir une chaîne JSON en dict à l'aide de Python

415

Je suis un peu confus avec JSON en Python. Pour moi, cela ressemble à un dictionnaire, et pour cette raison, j'essaie de le faire:

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

Mais quand je le fais print dict(json), cela donne une erreur.

Comment puis-je transformer cette chaîne en structure, puis appeler json["title"]pour obtenir un "exemple de glossaire"?

Frias
la source

Réponses:

756

json.loads()

import json

d = json.loads(j)
print d['glossary']['title']
Ignacio Vazquez-Abrams
la source
9
Quelle est la différence entre json.load et json.loads?
Shivam Agrawal
5
@ShivamAgrawal: exactement ce qu'il dit sur l'étain .
Ignacio Vazquez-Abrams
64
@ShivamAgrawal: La différence est que l' .load()analyse d'un objet fichier; .loads()analyse un objet chaîne / unicode.
fyngyrz
1
Cela me dérange que l'auteur de cette fonction n'ait pas écrit de fonction wrapper pour effectuer une vérification de type sur les données transmises afin de choisir automatiquement la bonne fonction à appeler. Je n'aime pas non plus la vague nomenclature utilisée. Voici ce que j'ai écrit pour lutter contre cela: 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) je suis sûr que cela peut être amélioré, mais maintenant vous pouvez appeler d = read_json(j)un «str» ou un «fichier» json.
Jacques Mathieu
2
@JacquesMathieu, Salut Jacques, merci pour votre fonction, j'ai fait une amélioration mineure car j'utilise parfois des dictionnaires: def read_json (json_data): if (type (json_data) == str): # Pour les chaînes, retournez json.loads (json_data) elif (str (type (json_data)) == "<class '_io.TextIOWrapper'>"): #Pour les fichiers retournent json.load (json_data) elif (type (json_data) == dict): # Pour les dictionnaires, retournez json.loads (json.dumps (json_data))
Gabriel Aizcorbe
98

Quand j'ai commencé à utiliser json, j'étais confus et incapable de le comprendre pendant un certain temps, mais finalement j'ai obtenu ce que je voulais
Voici la solution simple

import json
m = {'id': 2, 'name': 'hussain'}
n = json.dumps(m)
o = json.loads(n)
print(o['id'], o['name'])
Hussain
la source
Pourquoi êtes-vous décharges (m) en premier?
Han Van Pham
Je l'ai utilisé pour démontrer la sérialisation et la désérialisation. Utiliser loads(..)sur '{"id": 2, "name": "hussain"}'devrait aussi être bien comme la réponse acceptée.
Hussain
1
les décharges et les charges fonctionnent parfaitement pour moi, alors que la réponse acceptée ne l'est pas, merci beaucoup @Hussain de m'avoir sauvé un time, pour info , j'essaie de faire loadsdes chaînes dynamiques avec l'encodage utf-8 ...
Mohammed Sufian
19

utiliser simplejson ou cjson pour les accélérations

import simplejson as json

json.loads(obj)

or 

cjson.decode(obj)
locojay
la source
16

Si vous faites confiance à la source de données, vous pouvez utiliser evalpour convertir votre chaîne en dictionnaire:

eval(your_json_format_string)

Exemple:

>>> 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
la source
1
La chaîne de votre exemple n'est pas JSON.
bfontaine
1
Vrai. Il se transforme en un dictionnaire, qui peut facilement être chargé / sauvegardé en JSON (et bien sûr, vous pourriez avoir besoin d'une fonction d'encodeur json personnalisé si votre dictionnaire n'a aucune valeur json).
kakhkAtion
3
Non. Vous ne devez jamais évaluer les données d'entrée comme un code. Cela peut être votre petit projet pour animaux de compagnie qui utilise des données en lesquelles vous avez confiance, mais un mauvais code peut être réutilisé et de mauvaises pratiques répétées dans de vrais projets, laissant un gros code de sécurité.
NetworkMeister
Et c'est pourquoi ma réponse commence par "si vous faites confiance à la source de données"! Mais c'est vrai, c'est plus un hack, et certainement pas la meilleure pratique.
kakhkAtion
Vous pouvez totalement faire confiance à la source de données si elle est la vôtre. Ceci est en fait utile pour convertir un objet JS stringified en un dic en une chaîne JSON appropriée.
Vadorequest