Python Dict vs JSON: What's Different and Why It Matters
Python dictionaries look like JSON but are fundamentally different. This guide covers every syntax difference, the serialisation ecosystem, and when each format is the right choice.
Python dicts and JSON look almost identical at a glance. Both use curly braces, both have key-value pairs, both support nesting. This surface similarity is exactly why the differences cause so many bugs — developers assume they're the same thing until something breaks in production.
They are not the same thing. Here's everything you need to know.
The Syntax Differences
Quoting
Python allows both single and double quotes for strings:
{'name': 'Alice'} # valid Python
{"name": "Alice"} # also valid Python
JSON requires double quotes, always:
{"name": "Alice"} # valid JSON
{'name': 'Alice'} # INVALID JSON
Booleans
Python: True, False (capital T and F)
JSON: true, false (lowercase)
{'active': True, 'verified': False} # Python
{"active": true, "verified": false} # JSON
Null / None
Python: None
JSON: null
{'score': None} # Python
{"score": null} # JSON
Tuples
Python has tuples; JSON has no equivalent:
{'coords': (40.7128, -74.0060)} # Python tuple
{"coords": [40.7128, -74.0060]} # JSON array (closest equivalent)
Key types
Python dict keys can be any hashable type: strings, integers, tuples:
{1: 'one', (0, 0): 'origin'} # valid Python dict
JSON keys must be strings:
{"1": "one"} # only string keys allowed
The Data Model Differences
Python dicts are a runtime data structure — they live in memory as Python objects. JSON is a serialisation format — it's text.
This distinction matters because:
- Python dicts can hold any Python object as a value (datetime, Decimal, custom class instances, lambda functions). JSON can only hold strings, numbers, booleans, null, arrays, and objects.
- Python dicts can have tuple or integer keys. JSON objects require string keys.
- Python dicts are ordered (as of Python 3.7). JSON objects are officially unordered (though most parsers preserve insertion order in practice).
Python's JSON Module
The standard way to convert between the two is Python's `json` module:
import json
data = {'name': 'Alice', 'active': True, 'score': None}
json_string = json.dumps(data)
# '{"name": "Alice", "active": true, "score": null}'
parsed = json.loads(json_string)
# {'name': 'Alice', 'active': True, 'score': None}
The module handles True → true, False → false, None → null automatically in both directions.
What json.dumps Can't Handle
By default, json.dumps raises a TypeError for non-JSON-serialisable values:
import json
from datetime import datetime
data = {'created_at': datetime.now()}
json.dumps(data)
# TypeError: Object of type datetime is not JSON serializable
Solutions:
- Use a custom encoder: json.dumps(data, default=str)
- Use a library like pydantic or dataclasses-json that handles serialisation
- Use orjson or ujson for faster serialisation with more type support
When to Use Python Dict vs JSON
Use Python dict when:
- Working within a Python codebase — pass dicts between functions, store in memory, manipulate in place
- You need Python-specific types (datetime, Decimal, Enum, set)
- Performance matters — dict operations are faster than parsing/serialising JSON
Use JSON when:
- Sending data over a network (HTTP APIs, WebSockets)
- Writing to disk for other systems to read
- Communicating between services in different languages
- Storing structured data in a database as a text or jsonb field
Django and Flask: The Serialisation Gap
The most common Python dict → JSON friction point is in web frameworks. Django's ORM returns QuerySet objects; Flask/FastAPI route handlers receive request.json as dicts.
The gap manifests at the boundary — turning database objects into API responses. This is why Django REST Framework serializers, Flask-Marshmallow, and FastAPI's Pydantic models exist: they bridge the Python object model to JSON's stricter type system.
When debugging these boundaries — inspecting what a model instance contains, or what a request payload looks like — you're constantly copying Python dict repr output and wanting JSON. That's what DevConvert's Python Dict converter handles.