leer guardar dict diccionario datos create convertir array python json

guardar - leer json python



¿Cómo uso el módulo ''json'' para leer en un objeto JSON a la vez? (3)

Tengo un archivo JSON multi-gigabyte. El archivo está formado por objetos JSON que no son más que unos pocos miles de caracteres, pero no hay saltos de línea entre los registros.

Con Python 3 y el módulo json , ¿cómo puedo leer un objeto JSON a la vez desde el archivo a la memoria?

Los datos están en un archivo de texto plano. Aquí hay un ejemplo de un registro similar. Los registros reales contienen muchos diccionarios y listas anidadas.

Grabar en formato legible:

{ "results": { "__metadata": { "type": "DataServiceProviderDemo.Address" }, "Street": "NE 228th", "City": "Sammamish", "State": "WA", "ZipCode": "98074", "Country": "USA" } } }

Formato actual. Los nuevos registros comienzan uno tras otro sin interrupciones.

{"results": { "__metadata": {"type": "DataServiceProviderDemo.Address"},"Street": "NE 228th","City": "Sammamish","State": "WA","ZipCode": "98074","Country": "USA" } } }{"results": { "__metadata": {"type": "DataServiceProviderDemo.Address"},"Street": "NE 228th","City": "Sammamish","State": "WA","ZipCode": "98074","Country": "USA" } } }{"results": { "__metadata": {"type": "DataServiceProviderDemo.Address"},"Street": "NE 228th","City": "Sammamish","State": "WA","ZipCode": "98074","Country": "USA" } } }


Aquí hay una pequeña modificación de la solución de Martijn Pieters , que manejará cadenas JSON separadas con espacios en blanco.

def json_parse(fileobj, decoder=json.JSONDecoder(), buffersize=2048, delimiters=None): remainder = '''' for chunk in iter(functools.partial(fileobj.read, buffersize), ''''): remainder += chunk while remainder: try: stripped = remainder.strip(delimiters) result, index = decoder.raw_decode(stripped) yield result remainder = stripped[index:] except ValueError: # Not enough data to decode, read more break

Por ejemplo, si data.txt contiene cadenas JSON separadas por un espacio:

{"business_id": "1", "Accepts Credit Cards": true, "Price Range": 1, "type": "food"} {"business_id": "2", "Accepts Credit Cards": true, "Price Range": 2, "type": "cloth"} {"business_id": "3", "Accepts Credit Cards": false, "Price Range": 3, "type": "sports"}

entonces

In [47]: list(json_parse(open(''data''))) Out[47]: [{u''Accepts Credit Cards'': True, u''Price Range'': 1, u''business_id'': u''1'', u''type'': u''food''}, {u''Accepts Credit Cards'': True, u''Price Range'': 2, u''business_id'': u''2'', u''type'': u''cloth''}, {u''Accepts Credit Cards'': False, u''Price Range'': 3, u''business_id'': u''3'', u''type'': u''sports''}]


En términos generales, colocar más de un objeto JSON en un archivo hace que ese archivo no sea válido, JSON dañado . Dicho esto, aún puede analizar datos en fragmentos utilizando el método JSONDecoder.raw_decode() .

Lo siguiente producirá objetos completos a medida que el analizador los encuentre:

from json import JSONDecoder from functools import partial def json_parse(fileobj, decoder=JSONDecoder(), buffersize=2048): buffer = '''' for chunk in iter(partial(fileobj.read, buffersize), ''''): buffer += chunk while buffer: try: result, index = decoder.raw_decode(buffer) yield result buffer = buffer[index:] except ValueError: # Not enough data to decode, read more break

Esta función leerá fragmentos del objeto de archivo dado en trozos de buffersize , y buffersize que el objeto decoder buffersize objetos JSON completos del búfer. Cada objeto analizado se cede al llamante.

Úsalo así:

with open(''yourfilename'', ''r'') as infh: for data in json_parse(infh): # process object

Use esto solo si sus objetos JSON están escritos en un archivo consecutivo, sin nuevas líneas entre ellos. Si tiene líneas nuevas y cada objeto JSON está limitado a una sola línea, tiene un documento de líneas JSON , en cuyo caso puede usar Cargar y analizar un archivo JSON con varios objetos JSON en Python .


Si sus documentos JSON contienen una lista de objetos, y desea leer un objeto a la vez, puede usar el analizador iterativo JSON ijson para el trabajo. Solo leerá más contenido del archivo cuando necesite decodificar el siguiente objeto.

Tenga en cuenta que debe usarlo con la biblioteca YAJL , de lo contrario probablemente no verá ningún aumento de rendimiento.

Dicho esto, a menos que su archivo sea realmente grande , leerlo completamente en la memoria y luego analizarlo con el módulo JSON normal probablemente seguirá siendo la mejor opción.