2012-08-30 11 views
8

ho la seguente stringa:Parse un solo livello di JSON

'{ 
    "key1": "val1", 
    "key2": ["a","b", 3], 
    "key3": {"foo": 27, "bar": [1, 2, 3]} 
}' 

voglio analizzare solo il livello in modo risultato dovrebbe essere un dizionario di un livello con la chiave e il valore dovrebbe essere solo una stringa (don' t bisogno di analizzarlo)

per data stringa mi dovrebbe dare seguito dizionario:

{ 
    "key1": "val1", 
    "key2": "['a','b', 3]", 
    "key3": "{'foo': 27, 'bar': [1, 2, 3]}" 
} 

c'è un modo veloce per farlo? Senza analizzare tutta la stringa in json e convertire tutti i valori in stringhe.

+0

si deve analizzare l'intera stringa JSON, e afferrare le parti degli archi .. è fattibile, ma dubito che sia valsa la pena . Le prestazioni sono davvero critiche? –

+0

sì, dovrebbe essere parte del codice critico delle prestazioni –

+0

Anche se io converto direttamente ciascun valore in str, riceverò fastidiosi prefissi u per le stringhe: 'foo = json.loads ('{" key1 ":" val1 "," key2 " : ["a", "b", 3], "key3": {"foo": 27, "bar": [1, 2, 3]}} ') ' ' dict ([(k, str (v)) per k, v in foo.iteritems()]) ' mi darà: ' {u'key1 ':' val1 ', u'key2': "[u'a ', u'b' , 3] ", u'key3 ':" {u'foo': 27, u'bar ': [1, 2, 3]} "' –

risposta

3

Quasi una risposta, ma vedo solo due possibilità:

  1. Caricare il JSON completo e scaricare di nuovo i valori, che hanno escluso nella tua domanda
  2. modificare il contenuto avvolgendo i valori in citazioni, in modo che il carico rendimenti stringa JSON valori

Per essere onesti, penso che ci sia una cosa come 'prestazioni critiche JSON codice di analisi', suona solo sbagliato, quindi mi piacerebbe andare con la prima scelta sopra.

1

non lo faccio ora, se è veramente quello che ti serve, ma cerco

>>> import json 
>>> val = """ 
... { 
... "key1": "val1", 
... "key2": ["a","b", 3], 
... "key3": {"foo": 27, "bar": [1, 2, 3]} 
... } 
... """ 
>>> dict((k,json.dumps(v)) for k,v in json.loads(val).items()) 
{u'key3': '{"foo": 27, "bar": [1, 2, 3]}', u'key2': '["a", "b", 3]', u'key1': '"val1"'} 

E 'po' difficile, perché si carica a JSON oggetto pieno e non solo il dump di nuovo i valori nel dizionario.

+1

"Senza analizzare tutta la stringa in json e convertire tutti i valori in stringhe". –

1

Penso che si possa risolvere questo usando regex, si sta lavorando per me:

import re 
pattern = re.compile('"([a-zA-Z0-9]+)"\s*:\s*(".*"|\[.*\]|\{.*\})')  
dict(re.findall(pattern, json_string)) 

ma non so se questo è più veloce, è necessario provare a utilizzare i dati.

[EDIT]

Sì, è più veloce. Ho provato gli script qui sotto e la versione regex è 5 volte più veloce.

utilizzando il modulo JSON:

import json 

val=''' 
{ 
    "key1": "val1", 
    "key2": ["a","b", 3], 
    "key3": {"foo": 27, "bar": [1, 2, 3]} 
} 
''' 

for n in range(100000): 
    dict((k,json.dumps(v)) for k,v in json.loads(val).items()) 

usando espressioni regolari:

import re 

val='''{ 
    "key1": "val1", 
    "key2": ["a","b", 3], 
    "key3": {"foo": 27, "bar": [1, 2, 3]} 
}''' 

pattern = re.compile('"([a-zA-Z0-9]+)"\s*:\s*(".*"|\[.*\]|\{.*\})')  
for n in range(100000): 
    dict(re.findall(pattern, val))