pythonjsonextended-ascii

How to print Extended ASCII characters correctly with json.dumps() - Python


I have this JSON file with some characters that belongs to Extended ASCII characters, for example », •, ñ, Ó, Ä

{
    "@index": "1",
    "row": [
    {
        "col": [
        {
            "text": {
            "@x": "1",
            "#text": "Text » 1 A\\CÓ"
            }
        }
        ]
    },
    {
        "col": [
        {
            "text": {
            "@x": "7",
            "#text": "Text • 2 Wñ"
            }
        }
        ]
    }
    ]
}

I load it in d variable with json.load() as below

import json 

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

and d looks like this:

d = {'@index': '1', 'row': [{'col': [{'text': {'@x': '1', '#text': 'Text » 1 A\\CÓ'}}]}, {'col': [{'text': {'@x': '7', '#text': 'Text • 2 Wñ'}}]}]}

Then applying the following code, the json stored in d is converted to one level nested json (Until here, the extended ASCII characters are fine)

>>> z = {**d, 'row':[c['text'] for b in d['row'] for c in b['col']]}
>>> z
{'@index': '1', 'row': [{'@x': '1', '#text': 'Text » 1 A\\CÓ'}, {'@x': '7', '#text': 'Text • 2 Wñ'}]}
>>>

The issue comes when I use json.dumps() because the extended ASCII characters are printed wrong as you can see below.

How to fix this? Thanks for any help.

>>> print(json.dumps(z, indent=4))
{
    "@index": "1",
    "row": [
        {
            "@x": "1",
            "#text": "Text \u00bb 1 A\\C\u00d3"
        },
        {
            "@x": "7",
            "#text": "Text \u2022 2 W\u00f1"
        }
    ]
}
>>>

Solution

  • You're looking for the ensure_ascii parameter.

    import json                   
    
    raw_data = '{"data": ["»", "•", "ñ", "Ó", "Ä"]}'
    json_data = json.loads(raw_data)
    
    print(json_data)
    # {u'data': [u'\xbb', u'\u2022', u'\xf1', u'\xd3', u'\xc4']}
    
    processed_data = json.dumps(json_data, indent=4, ensure_ascii=False, encoding='utf-8')
    
    print(processed_data)
    # {
    #     "data": [
    #         "»", 
    #         "•", 
    #         "ñ", 
    #         "Ó", 
    #         "Ä"
    #     ]
    # }
    

    For Python2 you'd do:

    processed_data = json.dumps(json_data, indent=4, ensure_ascii=False).encode('utf-8')