1503 votes

Pourquoi Python ne peut pas analyser ces données JSON ?

J'ai ce JSON dans un fichier :

{
    "maps": [
        {
            "id": "blabla",
            "iscategorical": "0"
        },
        {
            "id": "blabla",
            "iscategorical": "0"
        }
    ],
    "masks": [
        "id": "valore"
    ],
    "om_points": "value",
    "parameters": [
        "id": "valore"
    ]
}

J'ai écrit ce script pour imprimer toutes les données JSON :

import json
from pprint import pprint

with open('data.json') as f:
    data = json.load(f)

pprint(data)

Ce programme soulève cependant une exception :

Traceback (most recent call last):
  File "<pyshell#1>", line 5, in <module>
    data = json.load(f)
  File "/usr/lib/python3.5/json/__init__.py", line 319, in loads
    return _default_decoder.decode(s)
  File "/usr/lib/python3.5/json/decoder.py", line 339, in decode
    obj, end = self.raw_decode(s, idx=_w(s, 0).end())
  File "/usr/lib/python3.5/json/decoder.py", line 355, in raw_decode
    obj, end = self.scan_once(s, idx)
json.decoder.JSONDecodeError: Expecting ',' delimiter: line 13 column 13 (char 213)

Comment puis-je analyser le JSON et extraire ses valeurs ?

0 votes

@kederrac Pour la raison invoquée : "Cette question a été causée par une faute de frappe ou un problème qui ne peut plus être reproduit". Le json n'est pas valide.

0 votes

@kederrac Le problème est causé par une erreur d'utilisation et non parce qu'il peut être reproduit.

2193voto

Justin Peel Points 17348

Vos données ne sont pas valides JSON format. Vous avez [] alors que vous auriez dû {} :

  • [] sont pour les tableaux JSON, qui sont appelés list en Python
  • {} sont pour les objets JSON, qui sont appelés dict en Python

Voici à quoi devrait ressembler votre fichier JSON :

{
    "maps": [
        {
            "id": "blabla",
            "iscategorical": "0"
        },
        {
            "id": "blabla",
            "iscategorical": "0"
        }
    ],
    "masks": {
        "id": "valore"
    },
    "om_points": "value",
    "parameters": {
        "id": "valore"
    }
}

Ensuite, vous pouvez utiliser votre code :

import json
from pprint import pprint

with open('data.json') as f:
    data = json.load(f)

pprint(data)

Avec les données, vous pouvez maintenant aussi trouver des valeurs comme ceci :

data["maps"][0]["id"]
data["masks"]["id"]
data["om_points"]

Essayez-les et voyez si cela commence à avoir du sens.

2 votes

Ok donc je dois contrôler mon code car ce fichier json est généré à partir d'un objet java. Merci.

0 votes

Les données sérialisées sont entourées de [] , et lorsque vous les lisez, vous avez besoin de f.read(), c'est-à-dire si vous utilisez la norme.

5 votes

Merci pour la solution. J'obtiens un symbole unicode lors de l'impression. (par exemple u'valore' ). Comment l'éviter ?

322voto

Bengt Points 2327

Su data.json devrait ressembler à ceci :

{
 "maps":[
         {"id":"blabla","iscategorical":"0"},
         {"id":"blabla","iscategorical":"0"}
        ],
"masks":
         {"id":"valore"},
"om_points":"value",
"parameters":
         {"id":"valore"}
}

Votre code devrait être :

import json
from pprint import pprint

with open('data.json') as data_file:    
    data = json.load(data_file)
pprint(data)

Notez que cela ne fonctionne qu'avec Python 2.6 et plus, car cela dépend de l'option with -Déclaration . En Python 2.5, utilisez from __future__ import with_statement dans Python <= 2.4, voir La réponse de Justin Peel sur lequel cette réponse est basée.

Vous pouvez maintenant aussi accéder à des valeurs uniques comme ceci :

data["maps"][0]["id"]  # will return 'blabla'
data["masks"]["id"]    # will return 'valore'
data["om_points"]      # will return 'value'

7 votes

J'ai reçu un downvote pour ça. Peut-être que ce n'était pas clair, pourquoi je pensais qu'une autre réponse était nécessaire. J'ai ajouté une note sur la compatibilité de l'énoncé with.

0 votes

Désolé pour le retour en arrière, mais le code suggéré garderait data_file open plus longtemps que nécessaire.

0 votes

En se référant à la documentation de la version 2.6 ( docs.python.org/2.6/library/io.html ), l'ouverture d'un fichier dans le contexte "avec" fermera automatiquement le fichier.

76voto

Geng Jiawen Points 85

La réponse de Justin Peel est vraiment utile, mais si vous utilisez Python 3, la lecture de JSON doit se faire de la manière suivante :

with open('data.json', encoding='utf-8') as data_file:
    data = json.loads(data_file.read())

Note : utiliser json.loads au lieu de json.load . Dans Python 3, json.loads prend un paramètre de type chaîne de caractères. json.load prend un paramètre d'objet de type fichier. data_file.read() renvoie un objet de type chaîne de caractères.

Pour être honnête, je ne pense pas que ce soit un problème de charger toutes les données json en mémoire dans la plupart des cas. Je vois cela dans JS, Java, Kotlin, cpp, rust presque tous les langages que j'utilise. Considérer la question de la mémoire comme une blague pour moi :)

D'un autre côté, je ne pense pas que l'on puisse analyser un fichier json sans le lire en entier.

11 votes

Pourquoi json.load être évitée au profit de .loads dans Python 3 ?

0 votes

@Zearin pls vérifier la document officiel .

10 votes

La page que vous avez liée ne dit rien sur le fait d'éviter load .

58voto

user1743724 Points 79
data = []
with codecs.open('d:\output.txt','rU','utf-8') as f:
    for line in f:
       data.append(json.loads(line))

9 votes

C'est la bonne solution si vous avez plusieurs objets json dans un fichier. json.loads ne décode pas les objets json multiples. Sinon, vous obtenez l'erreur "Extra Data".

0 votes

C'est la meilleure réponse. Sinon, cela donne l'erreur 'Extra Data'.

40 votes

La présence de plusieurs objets json dans un fichier signifie que le fichier lui-même n'est pas un json valide. Si vous avez plusieurs objets à inclure dans un fichier json, ils doivent être contenus dans un tableau au niveau supérieur du fichier.

14voto

moeabdol Points 2240

"Ultra JSON" ou simplement "ujson" peut gérer le fait d'avoir [] dans votre fichier d'entrée JSON. Si vous lisez un fichier d'entrée JSON dans votre programme sous la forme d'une liste d'éléments JSON, par exemple, [{[{}]}, {}, [], etc...] ujson peut gérer n'importe quel ordre arbitraire de listes de dictionnaires, de dictionnaires de listes.

Vous pouvez trouver ujson dans le Index des paquets Python et l'API est presque identique à l'API intégrée de Python. json bibliothèque.

ujson est également beaucoup plus rapide si vous chargez des fichiers JSON plus volumineux. Vous pouvez voir les détails de la performance en comparaison avec d'autres bibliothèques Python JSON dans le même lien fourni.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X