1

I'm looking to output a Python dictionary to a file using the json library with formatting such that lists are represented on the same line.

I have tried making a custom encoder and using the ones I have found online as well such as the suggestion here: https://stackoverflow.com/a/26512016/1411362

such that the final code line is:

import json


data = {'a':1, 'b':[1,2,3,4]}
with open("data.json", 'w') as f:
    json.dump(data, f, indent=4, cls=CustomEncoderClass)

however, this fails to work if I try to use json.dump to export as a file instead of json.dumps (like in the link above) to a string. Is there a way to use the custom encoder such that it works when I export the data to a file?

Martin Gergov
  • 1,556
  • 4
  • 20
  • 29
Viraj Shah
  • 11
  • 1
  • 1
    `json.dumps` with your `CustomEncoderClass` works? Then you can write the string with `f.write(json.dumps(...))` – Andrej Kesely Jul 16 '19 at 18:10
  • Indeed, the approach shown that works with `json.dumps()` doesn't with `json.dump()`. See my [answer](https://stackoverflow.com/a/42721412/355230) to another question that solved a similar problem. – martineau Jul 16 '19 at 18:20
  • @martineau Thanks, I was able to replicate your results from that post. However, this approach doesn't seem to work if I change this from a `NoIndent` object to any general list or tuple `if isinstance(obj, NoIndent)` to `if isinstance(obj, (list, tuple))`. Any idea why this is the case? I'm not exactly clear on how your default function (which string formats the object id) replaces the overridden default which seems to wrap everything in `iter`. – Viraj Shah Jul 16 '19 at 19:13
  • Viraj: AFAIK you can't change what the `json.JSONEncoder` does with respect to the Python types it supports by default shown in this [table](https://docs.python.org/3/library/json.html#json.JSONEncoder) in the documentation. Without going into all the details, basically what the code in my answer(s) do is workaround that by wrapping `list` and `tuple` objects in instances of a custom `NoIndent` wrapper class which allows the handling of them to be intercepted since that's not one of the types in the table (which is the only time `JSONEncoder` calls its `default()` method). – martineau Jul 16 '19 at 20:10

0 Answers0