JSON vs Python dict: the differences that matter
Why a JSON string is not a valid Python dict, the exact keywords that differ, and how to read a Python literal back safely at runtime.
They look alike but they are not the same
A Python dictionary and a JSON object share the same curly-brace, key-and-colon shape, which is why people paste one where the other belongs and hit a syntax error. JSON is a text interchange format with a strict, language-neutral grammar. A Python dict is a live object described by Python source code. The overlap is real but partial, and the gaps are exactly the things that break a naive copy and paste.
The keywords that break a direct paste
JSON writes booleans in lowercase as true and false, and it writes an absent value as null. Python writes True and False with capital letters and uses None for a missing value. So the JSON fragment with ok set to true and note set to null is a syntax error in Python until those become True and None. JSON also requires double quotes around every string and key, while Python happily accepts single quotes and treats them as the idiomatic default.
Reading a literal back: literal_eval, not eval
If you need to turn the converted text back into a real object at runtime, reach for ast.literal_eval from the standard library. It parses a string containing a Python literal (dicts, lists, strings, numbers, True, False, None) and nothing else, so it cannot run arbitrary code. Avoid the built-in eval for this job: eval will execute whatever it is given, which turns untrusted input into a remote code execution risk. If your data really is JSON, json.loads is faster and stricter still.
When to convert and when to import json
Convert to a Python literal when you want a value baked into your source code, such as a fixture, a default config, or a quick constant while prototyping. Prefer loading with json.loads when the data arrives at runtime from a file, an API, or a database, because that keeps the data separate from your code and handles encoding for you. This tool is built for the first case: it gives you a clean, escaped, indented literal to drop into a module.