¿Cómo imprimir un archivo JSON?

¿Cómo imprimo un archivo JSON en Python?

preguntado Oct 17 '12, 22:10

Intenta analizar el JSON usando json.loads() e imprima bastante ese diccionario resultante. O simplemente salta a la Bonita impresión sección de Python documentación para json. -

@Blender si publica una respuesta, le daré crédito ... esto podría cerrarse como un duplicado, porque la solución es la misma, pero la pregunta es diferente, así que quizás no. -

Por qué no <your_file.js python -mjson.tool como en el enlace de @ed? -

No creo que esté duplicado porque la impresión bonita desde la línea de comandos no es lo mismo que la impresión bonita mediante programación desde Python. Votación para reabrir. -

14 Respuestas

EL json módulo ya implementa algunas impresiones bonitas básicas en el dump y dumps funciones, con el indent parámetro que especifica cuántos espacios sangrar por:

>>> import json
>>>
>>> your_json = '["foo", {"bar":["baz", null, 1.0, 2]}]'
>>> parsed = json.loads(your_json)
>>> print(json.dumps(parsed, indent=4, sort_keys=True))
[
    "foo", 
    {
        "bar": [
            "baz", 
            null, 
            1.0, 
            2
        ]
    }
]

Para analizar un archivo, utilice json.load():

with open('filename.txt', 'r') as handle:
    parsed = json.load(handle)

Respondido el 29 de diciembre de 21 a las 22:12

Para una simple impresión bonita, esto también funciona sin un análisis explícito: print json.dumps(your_json_string, indent=4) - peterino

Sin la sangría, solo obtienes una sola línea de texto feo, por eso vine aquí. - krs013

Esto es similar a JavaScript var str = JSON.stringify(obj, null, 4); como se discutió aquí stackoverflow.com/questions/4810841/… - christophe roussy

@Peterino, no funciona sin un análisis explícito. Imprime una línea escapada - LCA

En la herramienta JS más bonita, no agregará 'salto de línea' si el ancho de línea es inferior a 80. Lo estoy buscando. - peterlits zo

Puede hacer esto en la línea de comando:

python3 -m json.tool some.json

(como ya se mencionó en los comentarios a la pregunta, gracias a @Kai Petzke por la sugerencia de python3).

En realidad, Python no es mi herramienta favorita en lo que respecta al procesamiento json en la línea de comandos. Para una impresión simple y bonita está bien, pero si desea manipular el json, puede volverse demasiado complicado. Pronto necesitará escribir un archivo de secuencia de comandos separado, podría terminar con mapas cuyas claves son u"alguna clave" (python unicode), lo que dificulta la selección de campos y realmente no va en la dirección de bastante -impresión.

También puedes usar jq:

jq . some.json

y obtienes colores como bonificación (y una extensibilidad mucho más fácil).

Anexo: Hay cierta confusión en los comentarios sobre el uso de jq para procesar archivos JSON grandes por un lado y tener un programa jq muy grande por el otro. Para la impresión bonita de un archivo que consta de una sola entidad JSON grande, la limitación práctica es la memoria RAM. Para la impresión bonita de un archivo de 2 GB que consiste en una sola matriz de datos del mundo real, el "tamaño máximo del conjunto residente" requerido para la impresión bonita era de 5 GB (ya sea que se use jq 1.5 o 1.6). Tenga en cuenta también que jq se puede usar desde Python después de pip install jq.

Respondido 25 Abr '20, 10:04

JQ es excelente, pero hay un límite máximo, por lo que es inútil para archivos grandes. (es decir, explota al manejar un archivo de 1.15 MB) github.com/stedolan/jq/issues/1041 - Chris McKee

sí, hombre, definitivamente, si estás escribiendo filtros jq con más de 10 XNUMX líneas de código, creo que estás intentando algo como ir a Marte en bicicleta. - gismo ranas

lol :D @gismo-ranas La versión json.tool canalizada a un archivo funciona realmente bien en archivos grandes; y es estúpidamente rápido. Me gusta JQ, pero formatear cualquier cosa más allá de una pequeña carga útil (que podrías hacer en la mayoría de los editores de texto) está fuera de su alcance :) Adición aleatoria: json-generator.com es una buena herramienta para hacer datos de prueba - Chris McKee

o simplemente: jq '' < some.json - error fatal

En realidad, recomiendo encarecidamente usar python3 -m json.tool <IN >OUT, ya que esto mantiene el orden original de los campos en los dictados JSON. La versión 2 del intérprete de Python ordena los campos en orden alfabético ascendente, que a menudo no es lo que desea. - Kai Petzke

Podrías usar el módulo incorporado pprint (https://docs.python.org/3.9/library/pprint.html).

Cómo puede leer el archivo con datos json e imprimirlo.

import json
import pprint

json_data = None
with open('file_name.txt', 'r') as f:
    data = f.read()
    json_data = json.loads(data)

print(json_data)
{"firstName": "John", "lastName": "Smith", "isAlive": "true", "age": 27, "address": {"streetAddress": "21 2nd Street", "city": "New York", "state": "NY", "postalCode": "10021-3100"}, 'children': []}

pprint.pprint(json_data)
{'address': {'city': 'New York',
             'postalCode': '10021-3100',
             'state': 'NY',
             'streetAddress': '21 2nd Street'},
 'age': 27,
 'children': [],
 'firstName': 'John',
 'isAlive': True,
 'lastName': 'Smith'}

El resultado no es un json válido, porque pprint usa comillas simples y la especificación json requiere comillas dobles.

Si desea reescribir el json con formato de impresión bonita en un archivo, debe usar pprint.pformat.

pretty_print_json = pprint.pformat(json_data).replace("'", '"')

with open('file_name.json', 'w') as f:
    f.write(pretty_print_json)

respondido 24 nov., 21:15

El problema con esto es que pprint usará comillas simples y dobles indistintamente, pero json solo requiere comillas dobles, por lo que es posible que su json pprinted ya no se analice como json válido. - drevicko

Sí, pero es solo para generar un archivo json. No tomar la salida y escribirla nuevamente en un archivo. - ikreb

la pregunta dice específicamente que imprima bastante un archivo json, no una representación de Python de un archivo json: Daniel Farrell

@DanielFarrell Tienes razón. Gracias. Actualicé mi respuesta. - ikreb

Pygmentize + Python json.tool = Pretty Print con resaltado de sintaxis

Pygmentize es una herramienta asesina. Mira esto.

Combino python json.tool con pygmentize

echo '{"foo": "bar"}' | python -m json.tool | pygmentize -l json

Consulte el enlace anterior para obtener instrucciones de instalación de pygmentize.

Una demostración de esto está en la siguiente imagen:

manifestación

Respondido el 30 de enero de 18 a las 09:01

En tu ejemplo -g en realidad no funciona;) Dado que la entrada proviene de stdin, pygmentize no puede hacer una buena suposición. Debe especificar lexer explícitamente: echo '{"foo": "bar"}' | python -m json.tool | pygmentize -l json - Denis la amenaza

@DenisTheMenace Solía ​​funcionar en 2015 cuando creé esta imagen de ejemplo. No parece estar funcionando ahora en mi sistema también. - Shubham Chaudhary

Usa esta función y no te preocupes por tener que recordar si tu JSON es un str or dict de nuevo, solo mire la bonita impresión:

import json

def pp_json(json_thing, sort=True, indents=4):
    if type(json_thing) is str:
        print(json.dumps(json.loads(json_thing), sort_keys=sort, indent=indents))
    else:
        print(json.dumps(json_thing, sort_keys=sort, indent=indents))
    return None

pp_json(your_json_string_or_dict)

Respondido el 14 de junio de 16 a las 04:06

Para poder imprimir bastante desde la línea de comando y poder tener control sobre la sangría, etc., puede configurar un alias similar a este:

alias jsonpp="python -c 'import sys, json; print json.dumps(json.load(sys.stdin), sort_keys=True, indent=2)'"

Y luego use el alias de una de estas maneras:

cat myfile.json | jsonpp
jsonpp < myfile.json

respondido 28 mar '17, 15:03

Utilice pprint: https://docs.python.org/3.6/library/pprint.html

import pprint
pprint.pprint(json)

print() en comparación con pprint.pprint()

print(json)
{'feed': {'title': 'W3Schools Home Page', 'title_detail': {'type': 'text/plain', 'language': None, 'base': '', 'value': 'W3Schools Home Page'}, 'links': [{'rel': 'alternate', 'type': 'text/html', 'href': 'https://www.w3schools.com'}], 'link': 'https://www.w3schools.com', 'subtitle': 'Free web building tutorials', 'subtitle_detail': {'type': 'text/html', 'language': None, 'base': '', 'value': 'Free web building tutorials'}}, 'entries': [], 'bozo': 0, 'encoding': 'utf-8', 'version': 'rss20', 'namespaces': {}}

pprint.pprint(json)
{'bozo': 0,
 'encoding': 'utf-8',
 'entries': [],
 'feed': {'link': 'https://www.w3schools.com',
          'links': [{'href': 'https://www.w3schools.com',
                     'rel': 'alternate',
                     'type': 'text/html'}],
          'subtitle': 'Free web building tutorials',
          'subtitle_detail': {'base': '',
                              'language': None,
                              'type': 'text/html',
                              'value': 'Free web building tutorials'},
          'title': 'W3Schools Home Page',
          'title_detail': {'base': '',
                           'language': None,
                           'type': 'text/plain',
                           'value': 'W3Schools Home Page'}},
 'namespaces': {},
 'version': 'rss20'}

contestado el 17 de mayo de 19 a las 19:05

pprint no produce un documento JSON válido. - selurvedu

@selurvedu, ¿qué significa eso y por qué es importante? - Charlie Parker

@CharlieParker Espero que hayan querido decir que saber que tiene un documento JSON válido es bastante útil. Claro, puedes usar el json módulo para trabajar con los datos y las claves del diccionario funcionan igual con cadenas entre comillas simples o dobles, pero algunas herramientas, por ejemplo Cartero y JSON Editor en línea, ambos esperan que las claves y los valores estén entre comillas dobles (según la especificación JSON). En todo caso, json.org especifica el uso de comillas dobles, que pprint no produce P.ej pprint.pprint({"name": "Jane"}) produce {'name': 'Jane'}. - fórmula digital

@CharlieParker, un ejemplo sería el 'language': None, en el resultado anterior, que debe ser "language": null. Nota la null y las comillas dobles. Lo que haces es imprimir bonito un objeto de Python. - Daniel F

Sí, eso es lo que quise decir. Gracias por aclararlo. :-)- selurvedu

def saveJson(date,fileToSave):
    with open(fileToSave, 'w+') as fileToSave:
        json.dump(date, fileToSave, ensure_ascii=True, indent=4, sort_keys=True)

Funciona para mostrarlo o guardarlo en un archivo.

Respondido el 09 de diciembre de 19 a las 16:12

Aquí hay un ejemplo simple de una bonita impresión de JSON en la consola de una manera agradable en Python, sin necesidad de que el JSON esté en su computadora como un archivo local:

import pprint
import json 
from urllib.request import urlopen # (Only used to get this example)

# Getting a JSON example for this example 
r = urlopen("https://mdn.github.io/fetch-examples/fetch-json/products.json")
text = r.read() 

# To print it
pprint.pprint(json.loads(text))

Respondido el 23 de enero de 18 a las 08:01

Recibo el siguiente mensaje de error en Python 3: "TypeError: el objeto JSON debe ser str, no 'bytes'" - Mr. T

Tu podrías intentar pprintjson.


INSTALACIÓN

$ pip3 install pprintjson

Uso

Bastante imprima JSON desde un archivo usando la CLI de pprintjson.

$ pprintjson "./path/to/file.json"

Pretty imprima JSON desde un stdin usando la CLI de pprintjson.

$ echo '{ "a": 1, "b": "string", "c": true }' | pprintjson

Bastante imprima JSON desde una cadena usando la CLI de pprintjson.

$ pprintjson -c '{ "a": 1, "b": "string", "c": true }'

Pretty imprima JSON desde una cadena con una sangría de 1.

$ pprintjson -c '{ "a": 1, "b": "string", "c": true }' -i 1

Pretty imprima JSON desde una cadena y guarde la salida en un archivo output.json.

$ pprintjson -c '{ "a": 1, "b": "string", "c": true }' -o ./output.json

Salida

enter image description here

Respondido 02 Oct 19, 06:10

¿En qué se diferencia tu sol de import pprint pprint.pprint(json)? - Charlie Parker

@CharlieParker Creo que produce un documento json válido, a diferencia de pprint, que usa comillas simples en lugar de comillas dobles: TheTechRobo representa a Ucrania

Creo que es mejor analizar el json antes, para evitar errores:

def format_response(response):
    try:
        parsed = json.loads(response.text)
    except JSONDecodeError:
        return response.text
    return json.dumps(parsed, ensure_ascii=True, indent=4)

Respondido 26 Abr '19, 08:04

Tenía un requisito similar para volcar el contenido del archivo json para iniciar sesión, algo rápido y fácil:

print(json.dumps(json.load(open(os.path.join('<myPath>', '<myjson>'), "r")), indent = 4 ))

si lo usa a menudo, póngalo en una función:

def pp_json_file(path, file):
    print(json.dumps(json.load(open(os.path.join(path, file), "r")), indent = 4))

respondido 12 nov., 20:22

Ojalá esto ayude a alguien más.

En el caso de que haya un error de que algo no es json serializable, las respuestas anteriores no funcionarán. Si solo desea guardarlo para que sea legible por humanos, entonces debe llamar recursivamente a la cadena en todos los elementos que no son de diccionario de su diccionario. Si desea cargarlo más tarde, guárdelo como un archivo pickle y luego cárguelo (por ejemplo, torch.save(obj, f) funciona bien).

Esto es lo que funcionó para mí:

#%%

def _to_json_dict_with_strings(dictionary):
    """
    Convert dict to dict with leafs only being strings. So it recursively makes keys to strings
    if they are not dictionaries.

    Use case:
        - saving dictionary of tensors (convert the tensors to strins!)
        - saving arguments from script (e.g. argparse) for it to be pretty

    e.g.

    """
    if type(dictionary) != dict:
        return str(dictionary)
    d = {k: _to_json_dict_with_strings(v) for k, v in dictionary.items()}
    return d

def to_json(dic):
    import types
    import argparse

    if type(dic) is dict:
        dic = dict(dic)
    else:
        dic = dic.__dict__
    return _to_json_dict_with_strings(dic)

def save_to_json_pretty(dic, path, mode='w', indent=4, sort_keys=True):
    import json

    with open(path, mode) as f:
        json.dump(to_json(dic), f, indent=indent, sort_keys=sort_keys)

def my_pprint(dic):
    """

    @param dic:
    @return:

    Note: this is not the same as pprint.
    """
    import json

    # make all keys strings recursively with their naitve str function
    dic = to_json(dic)
    # pretty print
    pretty_dic = json.dumps(dic, indent=4, sort_keys=True)
    print(pretty_dic)
    # print(json.dumps(dic, indent=4, sort_keys=True))
    # return pretty_dic

import torch
# import json  # results in non serializabe errors for torch.Tensors
from pprint import pprint

dic = {'x': torch.randn(1, 3), 'rec': {'y': torch.randn(1, 3)}}

my_pprint(dic)
pprint(dic)

salida:

{
    "rec": {
        "y": "tensor([[-0.3137,  0.3138,  1.2894]])"
    },
    "x": "tensor([[-1.5909,  0.0516, -1.5445]])"
}
{'rec': {'y': tensor([[-0.3137,  0.3138,  1.2894]])},
 'x': tensor([[-1.5909,  0.0516, -1.5445]])}

No sé por qué devolver la cadena y luego imprimirla no funciona, pero parece que debe colocar los volcados directamente en la declaración de impresión. Nota pprint como se ha sugerido ya funciona también. Tenga en cuenta que no todos los objetos se pueden convertir en un dictado con dict(dic) es por eso que parte de mi código tiene comprobaciones en esta condición.

Antecedentes:

Quería guardar las cadenas de pytorch pero seguía recibiendo el error:

TypeError: tensor is not JSON serializable

así que codifiqué lo anterior. Tenga en cuenta que sí, en pytorch usa torch.save pero los archivos pickle no son legibles. Revisa esta publicación relacionada: https://discuss.pytorch.org/t/typeerror-tensor-is-not-json-serializable/36065/3


PPrint también tiene argumentos de sangría, pero no me gustó cómo se ve:

    pprint(stats, indent=4, sort_dicts=True)

salida:

{   'cca': {   'all': {'avg': tensor(0.5132), 'std': tensor(0.1532)},
               'avg': tensor([0.5993, 0.5571, 0.4910, 0.4053]),
               'rep': {'avg': tensor(0.5491), 'std': tensor(0.0743)},
               'std': tensor([0.0316, 0.0368, 0.0910, 0.2490])},
    'cka': {   'all': {'avg': tensor(0.7885), 'std': tensor(0.3449)},
               'avg': tensor([1.0000, 0.9840, 0.9442, 0.2260]),
               'rep': {'avg': tensor(0.9761), 'std': tensor(0.0468)},
               'std': tensor([5.9043e-07, 2.9688e-02, 6.3634e-02, 2.1686e-01])},
    'cosine': {   'all': {'avg': tensor(0.5931), 'std': tensor(0.7158)},
                  'avg': tensor([ 0.9825,  0.9001,  0.7909, -0.3012]),
                  'rep': {'avg': tensor(0.8912), 'std': tensor(0.1571)},
                  'std': tensor([0.0371, 0.1232, 0.1976, 0.9536])},
    'nes': {   'all': {'avg': tensor(0.6771), 'std': tensor(0.2891)},
               'avg': tensor([0.9326, 0.8038, 0.6852, 0.2867]),
               'rep': {'avg': tensor(0.8072), 'std': tensor(0.1596)},
               'std': tensor([0.0695, 0.1266, 0.1578, 0.2339])},
    'nes_output': {   'all': {'avg': None, 'std': None},
                      'avg': tensor(0.2975),
                      'rep': {'avg': None, 'std': None},
                      'std': tensor(0.0945)},
    'query_loss': {   'all': {'avg': None, 'std': None},
                      'avg': tensor(12.3746),
                      'rep': {'avg': None, 'std': None},
                      'std': tensor(13.7910)}}

comparar con:

{
    "cca": {
        "all": {
            "avg": "tensor(0.5144)",
            "std": "tensor(0.1553)"
        },
        "avg": "tensor([0.6023, 0.5612, 0.4874, 0.4066])",
        "rep": {
            "avg": "tensor(0.5503)",
            "std": "tensor(0.0796)"
        },
        "std": "tensor([0.0285, 0.0367, 0.1004, 0.2493])"
    },
    "cka": {
        "all": {
            "avg": "tensor(0.7888)",
            "std": "tensor(0.3444)"
        },
        "avg": "tensor([1.0000, 0.9840, 0.9439, 0.2271])",
        "rep": {
            "avg": "tensor(0.9760)",
            "std": "tensor(0.0468)"
        },
        "std": "tensor([5.7627e-07, 2.9689e-02, 6.3541e-02, 2.1684e-01])"
    },
    "cosine": {
        "all": {
            "avg": "tensor(0.5945)",
            "std": "tensor(0.7146)"
        },
        "avg": "tensor([ 0.9825,  0.9001,  0.7907, -0.2953])",
        "rep": {
            "avg": "tensor(0.8911)",
            "std": "tensor(0.1571)"
        },
        "std": "tensor([0.0371, 0.1231, 0.1975, 0.9554])"
    },
    "nes": {
        "all": {
            "avg": "tensor(0.6773)",
            "std": "tensor(0.2886)"
        },
        "avg": "tensor([0.9326, 0.8037, 0.6849, 0.2881])",
        "rep": {
            "avg": "tensor(0.8070)",
            "std": "tensor(0.1595)"
        },
        "std": "tensor([0.0695, 0.1265, 0.1576, 0.2341])"
    },
    "nes_output": {
        "all": {
            "avg": "None",
            "std": "None"
        },
        "avg": "tensor(0.2976)",
        "rep": {
            "avg": "None",
            "std": "None"
        },
        "std": "tensor(0.0945)"
    },
    "query_loss": {
        "all": {
            "avg": "None",
            "std": "None"
        },
        "avg": "tensor(12.3616)",
        "rep": {
            "avg": "None",
            "std": "None"
        },
        "std": "tensor(13.7976)"
    }
}

Respondido 16 Feb 21, 18:02

Está lejos de ser perfecto, pero hace el trabajo.

data = data.replace(',"',',\n"')

puede mejorarlo, agregar sangría, etc., pero si solo desea poder leer un json más limpio, este es el camino a seguir.

Respondido 01 Abr '20, 15:04

AttributeError: el objeto 'dict' no tiene el atributo 'replace' - AjayKumarBasuthkar

¿No estropeará esto el archivo si tiene una coma en una cadena? - TheTechRobo representa a Ucrania

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.