Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pretty printing Python dictionary/lists in "Black style"

I don't really fancy the way Python's pprint formats the output. E.g.

import pprint
from datetime import datetime
d = {
    'a': [
        {
            '123': datetime(2021, 11, 15, 0, 0),
            '456': 'cillum dolore eu fugiat nulla pariatur. Excepteur sint...',
            '567': [
                1, 2, 'cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.'
            ]
        }
    ],
    'b': {
        'x': 'yz'
    }
}
pprint.pprint(d)

Will print:

{'a': [{'123': datetime.datetime(2021, 11, 15, 0, 0),
        '456': 'cillum dolore eu fugiat nulla pariatur. Excepteur sint...',
        '567': [1,
                2,
                'cupidatat non proident, sunt in culpa qui officia deserunt '
                'mollit anim id est laborum.']}],
 'b': {'x': 'yz'}}

But I'd like it to be:

{
    "a": [
        {
            "123": datetime.datetime(2021, 11, 15, 0, 0),
            "456": "cillum dolore eu fugiat nulla pariatur. Excepteur sint...",
            "567": [
                1,
                2,
                "cupidatat non proident, sunt in culpa qui officia deserunt "
                "mollit anim id est laborum.",
            ],
        }
    ],
    "b": {"x": "yz"},
}

I.e. in the style of Black

Is there a parameter of pprint or some 3rd party library to do this? I guess I could use Black for some outputs but I wonder if there is an out-of-the-box solution

Edit: A good suggestion was to use print(json.dumps(d, indent=4)). This does the job if the whole thing is JSON-serializable but unfortunately does not work otherwise.

like image 789
Ferrard Avatar asked Aug 03 '26 09:08

Ferrard


2 Answers

You want "Black style" – so why not use black itself?

from datetime import datetime
import black

d = {'a': [{'123': datetime(2021, 11, 15, 0, 0),
            '456': 'cillum dolore eu fugiat nulla pariatur. Excepteur sint...',
            '567': [1, 2, 'cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.']}],
     'b': {'x': 'yz'}}
print(black.format_str(str(d), mode=black.Mode(line_length=79)))

This prints (using black v24.10.0):

{
    "a": [
        {
            "123": datetime.datetime(2021, 11, 15, 0, 0),
            "456": "cillum dolore eu fugiat nulla pariatur. Excepteur sint...",
            "567": [
                1,
                2,
                "cupidatat non proident, sunt in culpa qui officia deserunt "
                "mollit anim id est laborum.",
            ],
        }
    ],
    "b": {"x": "yz"},
}

The idea here is to first get a more or less arbitrarily formatted string representation of the object to be printed, then have black format it as if it were a piece of code, using its format_str() function.

Here I am using str(d) to get the string representation, but maybe repr(d) and pprint.pformat(d) might be worth a look as well. With the given example, they all result in the same output though.

like image 200
simon Avatar answered Aug 05 '26 05:08

simon


If you just want the output to use 4 spaces per indentation level and don't necessarily need the strings to be enclosed in double quotes, an easy approach without involving a third-party library is to use reprlib.Repr and set the indent argument to 4 spaces.

By default reprlib.Repr limits the representation strings of various types to certain maximum lengths, but you can override them with respective arguments:

import sys
from reprlib import Repr

maxsize = sys.maxsize
pretty_repr = Repr(maxlevel=maxsize, maxtuple=maxsize, maxlist=maxsize,
    maxarray=maxsize, maxdict=maxsize, maxset=maxsize, maxfrozenset=maxsize,
    maxdeque=maxsize, maxstring=maxsize, maxlong=maxsize, maxother=maxsize,
    indent='    ').repr
print(pretty_repr(d))

With your given input, this outputs:

{
    'a': [
        {
            '123': datetime.datetime(2021, 11, 15, 0, 0),
            '456': 'cillum dolore eu fugiat nulla pariatur. Excepteur sint...',
            '567': [
                1,
                2,
                'cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.',
            ],
        },
    ],
    'b': {
        'x': 'yz',
    },
}

Demo here

like image 40
blhsing Avatar answered Aug 05 '26 06:08

blhsing



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!