Can json.loads ignore trailing commas?
is invalid syntax. For reasons mentioned in this other StackOverflow question, using a trailing comma is legal (and perhaps encouraged?) in Python code. I am working with both Python and JSON, so I would love to be able to be consistent across both types of files. Is there a way to have json.loads ignore trailing commas?
In short, no. The best practices or preferred approaches for one language have no bearing for the best practices in another.
In JSON, it’s invalid, so no, the JSON parser will report that as an invalid format (correct behavior!). If it’s a Python dictionary, you could parse it using ast.literal_eval .
The second example you gave isn’t JSON, but it is HOCON. github.com/typesafehub/config/blob/master/HOCON.md Kind of makes me want to write a parser for python.
@ChrisMartin — Hmmm, nope. Skimmed the spec, defines control-characters as from the JSON spec (big can of » \/worms/ ^I ^H «). It also will not accept numbers starting with a decimal (so javascript declarations like would be invalid. It employs # and // for comments, but provides no /* block comment method */ . Other than that, it’s awesome.
7 Answers 7
- JavaScript-style comments (both single and multi-line) are legal.
- Object keys may be unquoted if they are legal ECMAScript identifiers
- Objects and arrays may end with trailing commas.
- Strings can be single-quoted, and multi-line string literals are allowed.
Usage is consistent with python’s built in json module:
It does come with a warning:
It is fast enough for loading start up config etc.
You can wrap python’s json parser with jsoncomment
- Single and Multi line comments
- Multi line data strings
- Trailing commas in objects and arrays, after the last item
import json from jsoncomment import JsonComment with open(filename) as data_file: parser = JsonComment(json) data = parser.load(data_file)
That package isn’t very good. It removes commas from strings as well. Just have a string containing ,> or ,] and the commas will magically disappear.
@Sven Looks like they upgraded to a proper parse and abandoned regex: github.com/vaidik/commentjson/releases
If it has its own full-blown JSON parser why not just return the result of its parsing? This is parsing it, re-encoding it then parsing it again.
Strip the commas before you pass the value in.
import re def clean_json(string): string = re.sub(",[ \t\r\n]+>", ">", string) string = re.sub(",[ \t\r\n]+\]", "]", string) return string
@Cramer It fails on this JSON: <"key1": "
In python you can have trailing commas inside of dictionaries and lists, so we should be able to take advantage of this using ast.literal_eval:
import ast, json str = '' python_obj = ast.literal_eval(str) # python_obj is json_str = json.dumps(python_obj) # json_str is ''
However, JSON isn’t exactly python so there are a few edge cases to this. For example, values like null, true, false don’t exist in python. We can replace those with valid python equivalents before we run the eval:
import ast, json def clean_json(str): str = str.replace('null', 'None').replace('true', 'True').replace('false', 'False') return json.dumps(ast.literal_eval(str))
This will unfortunately mangle any strings that have the words null, true, or false in them.
Mangling of the words null, true, or false in a string is one heck of a downside, so thanks for highlighting it.
Cobbling together the knowledge from a few other answers, especially the idea of using literal_eval from @Porkbutts answer, I present a wildly-evil solution to this problem
def json_cleaner_loader(path): with open(path) as fh: exec("null=None;true=True;false=False;d=<>".format(fh.read())) return locals()["d"]
This works by defining the missing constants to be their Pythonic values before evaluating the JSON struct as Python code. The structure can then be accessed from locals() (which is yet another dictionary).
This should work with both Python 2.7 and Python 3.x
BEWARE this will execute whatever is in the passed file, which may do anything the Python interpreter can, so it should only ever be used on inputs which are known to be safe (ie. don’t let web clients provide the content) and probably not in any production environment.
This probably also fails if it’s given a very large amount of content.
Late addendum: A side effect of this (awful) approach is that it supports Python comments within the JSON (JSON-like?) data, though it’s hard to compare that to even friendly non-standard behavior.
Python json loads ignore
Last updated: Feb 18, 2023
Reading time · 2 min
# Convert JSON NULL values to None using Python
Use the json.loads() method to convert JSON NULL values to None in Python. The json.loads method parses a JSON string into a native Python object.
Conversely, the json.dumps method converts a Python object to a JSON formatted string.
Copied!import json my_json = r'' my_dict = json.loads(my_json) print(type(my_dict)) # 👉️ print(my_dict) # 👉️
The example shows how to convert null values to None using the json.loads() method.
# Convert JSON NULL values to Python None values
The json.loads method parses a JSON string into a native Python object.
Copied!import json json_str = r'' my_dict = json.loads(json_str) print(type(my_dict)) # 👉️
The process of converting a JSON string to a native Python object is called deserialization.
# Convert Python None values to JSON NULL values
You can use the json.dumps method to convert a Python object to a JSON formatted string.
Copied!import json my_json = r'' # ✅ convert NULL values to None (JSON string to Python object) my_dict = json.loads(my_json) print(type(my_dict)) # 👉️ print(my_dict) # 👉️ # ✅ convert None to null (Python object to JSON string) my_json_again = json.dumps(my_dict) print(my_json_again) # 👉️ ''
The process of converting a native Python object to a JSON string is called serialization.
You can also have None keys in Python objects, but it should generally be avoided.
Copied!import json my_dict = 'name': 'Bobby', None: None> print(my_dict) # 👉️ my_json = json.dumps(my_dict) print(my_json) # 👉️ '' my_dict_again = json.loads(my_json) print(my_dict_again) # 👉️
We started with a Python object that has a None key and a None value.
When we converted the object to JSON, both the key and the value got converted to null .
When we parsed the JSON string into a Python object, the value got converted to None , but the key is still the string null .
This is because JSON keys must be of type string . If we pass a key of any other type to the json.dumps() method, the key automatically gets converted to a string.
Once the key is converted to a string, parsing the JSON string will return a string key in the Python object.
# Additional Resources
You can learn more about the related topics by checking out the following tutorials:
I wrote a book in which I share everything I know about how to become a better, more efficient programmer.