2012-08-30 15 views
8

tengo la siguiente cadena:Analizar sólo un nivel de JSON

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

Quiero analizar sólo en el nivel de modo resultado debe ser un diccionario de una sola planta con llave, y el valor debe ser sólo una cadena (Don' t necesidad de analizarlo)

para cadena dada que me diera siguiente diccionario:

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

¿hay una forma rápida de hacerlo? Sin analizar cadenas enteras a json y convertir todos los valores a cadenas.

+0

que haya que analizar toda la cadena JSON, y agarrar las partes de cuerda .. es factible, pero dudo que vale la pena el esfuerzo . ¿El rendimiento es realmente crítico? –

+0

sí, debería ser parte del código crítico de rendimiento –

+0

Además, si convierto directamente cada valor en str, recibiré prefijos desagradables u para cadenas: 'foo = json.loads ('{" key1 ":" val1 "," key2 " : ["a", "b", 3], "key3": {"foo": 27, "bar": [1, 2, 3]}} ') ' ' dict ([(k, str (v)) para k, v en foo.iteritems()]) ' me dará: ' {u'key1 ':' val1 ', u'key2': "[u'a ', u'b' , 3] ", u'key3 ':" {u'foo': 27, u'bar ': [1, 2, 3]} ' –

Respuesta

3

Apenas una respuesta, pero sólo veo dos posibilidades:

  1. Cargar el JSON completa y volcar hacia atrás los valores, los cuales se han descartado en su pregunta
  2. modificar el contenido envolviendo los valores de cotizaciones, por lo que el rendimiento de carga cadena JSON valora

Para ser honesto, creo que no hay tal cosa como 'rendimiento crítico JSON código de análisis', suena mal, así que me gustaría ir con la primer opti en.

1

no lo hago ahora si es realmente lo que necesita, pero trata de

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

Es poco complicado, porque se carga a JSON objetos completo y que acaba de volcar hacia atrás en el diccionario de valores.

+1

"Sin analizar cadena completa a json y convertir todos los valores a cadenas". –

1

Creo que se puede solucionar esto usando expresiones regulares, que está trabajando para mí:

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

pero no sé si esto es más rápido, es necesario tratar de usar sus datos.

[EDIT]

Sí, es más rápido. Probé los scripts a continuación y la versión de expresiones regulares es 5 veces más rápida.

utilizando el módulo 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 expresiones regulares:

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)) 
Cuestiones relacionadas