21

I have this code:

import json

my_list = [1, 2, 3]
my_dict = {"key": "value", "boolean": True}
my_json = {"object": my_dict, "array": my_list}

print(json.dumps(my_json, indent=4))

I get an output like:

{
    "object": {
        "key": "value",
        "boolean": true
    },
    "array": [
        1,
        2,
        3
    ]
}

I want it the elements of the "array" array to appear on the same line, like so:

{
    "object": {
        "key": "value",
        "boolean": true
    },
    "array": [1, 2, 3]
}

How can I get this result?

5
  • 5
    Have you tried removing the indent=4 ? Commented Apr 30, 2017 at 15:50
  • 1
    I guess you could use regex to search & replace. But how do you want to handle more complex JSON that contains lists & dicts nested inside other lists & dicts? To get complete control you can implement your own class that inherits from json.JSONEncoder. Commented Apr 30, 2017 at 15:56
  • 6
    Closed, but the link in the close message points to a much too complicated answer. Use this: print(json.dumps(my_json, indent=None, separators=(",",":"))), which results in compact one-line form {"object":{"key":"value","boolean":true},"array":[1,2,3]} Commented Apr 3, 2020 at 8:33
  • An overeager close in me opinion. It's a very simple question and the close hint points to a very complex answer. mgaert above provided a one-liner that does the trick. Commented Jul 31, 2020 at 10:51
  • what about when the array is 100's or 1000's of items in length? how are you rendering the json string? maybe you can use a different program to render and explore the json like firefox or chrome browers which allow you to expand and collapse the shelves? Commented Jul 31, 2020 at 12:00

5 Answers 5

12

Your task can be fulfilled by using a library like jsbeautifier

Install the library by using:

pip install jsbeautifier

Then add the options and call the jsbeautifier.beautify() function.

Full Code:

import json
import jsbeautifier


my_list = [1, 2, 3]
my_dict = {"key": "value", "boolean": True}
my_json = {"object": my_dict, "array": my_list}

options = jsbeautifier.default_options()
options.indent_size = 2
print(jsbeautifier.beautify(json.dumps(my_json), options))

Output:

{
  "object": {
    "key": "value",
    "boolean": true
  },
  "array": [1, 2, 3]
}
Sign up to request clarification or add additional context in comments.

3 Comments

Does the project have a repo? Can't find anything for it...
awesome repo, it saved me an evening from reinventing a wheel.
2

You don't need any new module to solve this problem. The JSON output is a string type and you can use a loop and an if/elif/else to solve it as in the example below:

import json

my_list = [1, 2, 3]
my_dict = {"key": "value", "boolean": True}
my_json = {"object": my_dict, "array": my_list}

json_dumps = json.dumps(my_json, indent=4)

str_to_write = ''
skip = 0
for char in json_dumps :
    if (skip == 1) and ((char == '\n') or (char == ' ')) :
        pass
    elif (char == '[') :
        skip = 1
        str_to_write = str_to_write + char
    elif (char == ']') :
        skip = 0
        str_to_write = str_to_write + char
    else :
        str_to_write = str_to_write + char

print(str_to_write)

Unfortunatly, it also strips the space character inside the lists. The output is:

{
    "object": {
        "key": "value",
        "boolean": true
    },
    "array": [1,2,3]
}

Using regex module, you can keep the spaces:

import regex as re
import json

my_list = [1, 2, 3]
my_dict = {"key": "value", "boolean": True}
my_json = {"object": my_dict, "array": my_list}

json_dumps = json.dumps(my_json, indent=4)

start = [m.start() for m in re.finditer('\[', json_dumps)]
end = [m.start() + 1 for m in re.finditer('\]', json_dumps)]
original = []
alterated = []
for s, e in zip(start, end) :
    original.append(json_dumps[s:e])
    alterated.append(json_dumps[s:e].replace('\n', '').replace('    ', '').replace(',', ', '))
for o, a in zip(original, alterated) :
    json_dumps = json_dumps.replace(o, a)

print(json_dumps)

The output:

{
    "object": {
        "key": "value",
        "boolean": true
    },
    "array": [1, 2, 3]
}

1 Comment

The problem with this method that typically you still want to indent the lists that have nested elements. E.g. list like [ [1,1,3], [1,1,3] ] you want each sublist to be on their own line.
1

I have a solution but it's hacky and involving monkey patching json's library encoder.py.

import json
a = {
    "header": [["l","f","f"],["f","f","f"]],
    "data": [[1,1,3], [1,1,3]]
}
json.encoder.pretty_json_lists = True
print(json.dumps(a, indent=4))

Resulting in json like so:

{
    "header": [
        ["l","f","f"],
        ["f","f","f"]
    ],
    "data": [
        [1,1,3],
        [1,1,3]
    ]
}

Patched encoder.py can be found here - https://gist.github.com/Andrej730/38febfb059e12f3e67fe72703414ccf9

Comments

0

Per the python documentation you can just replace the separators.

Compact encoding:

>>>
>>> import json
>>> json.dumps([1, 2, 3, {'4': 5, '6': 7}], separators=(',', ':'))
'[1,2,3,{"4":5,"6":7}]'

Comments

0

Probably this won't help you much, but you could definitely use Regex (all white considering your context).

Here is code I used in one of my projects.

def pretty_json(data):
    """
    With the power of regex, remove the annoying \n inside an array in `le Jeson`
    Our input (json output) looks like this:
        {
        |    "num_nodes": 8,
        |    "adjacency_matrix": [
        |        [
        |            "",
        |            "H",
        |        ],
        |        [
        |            "E",
        |            0,
        |       ]
        |    ],
        |    "adjacency_list": {
        |    |   "H": [
        |    |       {
        |    |           "node": "F",
        |    |           "weight": 1
        |    |       },
        |    |       {
        |    |           "node": "G",
        |    |           "weight": 1
        |    |       }
        |    |   ],
        |    }
        }
    We'll turn this boi into something more readable
    """

    # define the necessary matches
    SBRACKET = r'\[\n\s+"'
    CBRACKET = r'\{\n\s+'

    C_INSIDE = r'",\n\s+'
    C_INSIDE_LF = r'(")\n\s+\]'

    D_INSIDEARR = r'(\d,)\n\s+'
    D_INSIDEARR_LF = r'(\d)\n\s+\]'
    D_INSIDEOBJ_LF = r'(\d)\n\s+\}'

    # replace all occurrences
    data = re.sub(SBRACKET, '[ "', data)
    data = re.sub(C_INSIDE, '", ', data)
    data = re.sub(D_INSIDEARR, r'\1 ', data)
    data = re.sub(D_INSIDEARR_LF, r'\1 ]', data)
    data = re.sub(C_INSIDE_LF, r'\1 ]', data)
    data = re.sub(CBRACKET, '{ ', data)
    data = re.sub(D_INSIDEOBJ_LF, r'\1 }', data)

    return data

Data generated by it (Not perfect)

{ "num_nodes": 8, "adjacency_matrix": [
        [ "", "S7", "S5", "S3", "S4", "S6", "S8", "S2", "S1" ],
        [ "S7", 0, 0, 0, 1, 1, 1, 0, 0 ],
        [ "S5", 0, 0, 1, 0, 1, 0, 1, 1 ],
        [ "S3", 0, 1, 0, 0, 1, 0, 0, 1 ],
        [ "S4", 1, 0, 0, 0, 1, 0, 1, 0 ],
        [ "S6", 1, 1, 1, 1, 0, 1, 0, 0 ],
        [ "S8", 1, 0, 0, 0, 1, 0, 0, 0 ],
        [ "S2", 0, 1, 0, 1, 0, 0, 0, 1 ],
        [ "S1", 0, 1, 1, 0, 0, 0, 1, 0 ]
    ],
    "adjacency_list": { "S7": [
            { "node": "S8", "weight": 1 },
            { "node": "S4", "weight": 1 },
            { "node": "S6", "weight": 1 }
        ],
        "S5": [
            { "node": "S1", "weight": 1 },
            { "node": "S6", "weight": 1 },
            { "node": "S3", "weight": 1 },
            { "node": "S2", "weight": 1 }
        ],
        "S3": [
            { "node": "S6", "weight": 1 },
            { "node": "S5", "weight": 1 },
            { "node": "S1", "weight": 1 }
        ],
        "S4": [
            { "node": "S7", "weight": 1 },
            { "node": "S6", "weight": 1 },
            { "node": "S2", "weight": 1 }
        ],
        "S6": [
            { "node": "S8", "weight": 1 },
            { "node": "S4", "weight": 1 }
        ],
        "S8": [
            { "node": "S6", "weight": 1 },
            { "node": "S7", "weight": 1 }
        ],
        "S2": [
            { "node": "S1", "weight": 1 },
            { "node": "S5", "weight": 1 }
        ],
        "S1": [
            { "node": "S5", "weight": 1 },
            { "node": "S3", "weight": 1 }
        ]
    }
}

Note that you have to json.dumps() your input first with an indent argument set

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.