DevConvert
Python

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.

7 min readJanuary 2026

Need to convert right now? The tool is free — no signup required.


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.


Try the Python Dict → JSON

Free, instant, and no signup required.