What Are the Differences Between Python Dictionary and JSON
Python dictionaries and JSON look nearly identical at first glance, both using curly braces and key-value pairs. This visual similarity causes frequent confusion, but they serve fundamentally different purposes. A dictionary is a data structure that lives in your program's memory. JSON is a text format designed for exchanging data between systems. Understanding the distinction is essential when working with APIs, configuration files, and data storage.
This guide explains the key differences, shows how to convert between the two formats, and covers common pitfalls that trip up developers.
Python Dictionary: An In-Memory Data Structure
A dictionary is a native Python object stored in RAM. It maps keys to values, supports various hashable types as keys, and can hold references to any Python object, including functions, classes, and custom instances:
from datetime import datetime
# Dictionaries support diverse key and value types
data = {
"name": "Alice",
1: "integer key", # Non-string keys are valid
(2, 3): "tuple key", # Any hashable type works
"active": True, # Python boolean (capital T)
"data": None # Python None (capital N)
}
print(type(data))
print(data[1])
print(data[(2, 3)])
Output:
<class 'dict'>
integer key
tuple key
Dictionaries can also store complex Python objects that have no equivalent in other languages:
from datetime import datetime
user = {
"name": "Bob",
"created": datetime.now(), # datetime object
"process": lambda x: x * 2, # function reference
"scores": {10, 20, 30} # set
}
print(type(user["created"]))
print(user["process"](5))
Output:
<class 'datetime.datetime'>
10
JSON: A Text Serialization Format
JSON (JavaScript Object Notation) is a string designed for data interchange between systems, languages, and platforms. It follows strict syntax rules that differ from Python in several important ways:
import json
# JSON is always a string
json_string = '{"name": "Alice", "age": 30, "active": true}'
print(type(json_string))
# Parse it into a Python dictionary
parsed = json.loads(json_string)
print(type(parsed))
Output:
<class 'str'>
<class 'dict'>
JSON has specific formatting requirements:
- Keys must be strings enclosed in double quotes
- String values must use double quotes (single quotes are invalid)
- Booleans are lowercase:
trueandfalse - Null values use the keyword
null - No trailing commas are allowed
Single quotes are the most common source of JSON parsing errors. Python accepts both quote styles for strings, but JSON strictly requires double quotes:
import json
# Wrong: single quotes are not valid JSON
bad_json = "{'name': 'Alice'}"
try:
json.loads(bad_json)
except json.JSONDecodeError as e:
print(f"Error: {e}")
# Correct: double quotes only
good_json = '{"name": "Alice"}'
result = json.loads(good_json)
print(result)
Output:
Error: Expecting property name enclosed in double quotes: line 1 column 2 (char 1)
{'name': 'Alice'}
Converting Between Dictionaries and JSON
The built-in json module provides two primary functions for conversion:
json.dumps(): Converts a Python dictionary to a JSON string (serialization)json.loads(): Converts a JSON string to a Python dictionary (deserialization)
import json
# Dictionary to JSON string
user_dict = {"name": "Alice", "age": 30, "active": True, "data": None}
json_string = json.dumps(user_dict)
print(f"JSON string: {json_string}")
print(f"Type: {type(json_string)}")
print()
# JSON string back to dictionary
parsed_dict = json.loads(json_string)
print(f"Dictionary: {parsed_dict}")
print(f"Type: {type(parsed_dict)}")
Output:
JSON string: {"name": "Alice", "age": 30, "active": true, "data": null}
Type: <class 'str'>
Dictionary: {'name': 'Alice', 'age': 30, 'active': True, 'data': None}
Type: <class 'dict'>
Notice how Python's True becomes JSON's true, and Python's None becomes JSON's null. These conversions happen automatically in both directions.
Handling Non-Serializable Types
JSON only supports a small set of basic types. If your dictionary contains Python-specific objects like datetime, set, or custom classes, json.dumps() will raise a TypeError. You need to provide a custom encoder to handle these types:
import json
from datetime import datetime
data = {
"event": "login",
"timestamp": datetime.now()
}
# This fails because datetime is not JSON serializable
try:
json.dumps(data)
except TypeError as e:
print(f"Error: {e}")
# Solution: provide a custom encoder function
def json_encoder(obj):
if isinstance(obj, datetime):
return obj.isoformat()
raise TypeError(f"Object of type {type(obj)} is not JSON serializable")
result = json.dumps(data, default=json_encoder)
print(result)
Output:
Error: Object of type datetime is not JSON serializable
{"event": "login", "timestamp": "2026-02-18T21:38:10.125495"}
Key Pitfall: Integer Keys Become Strings
JSON only supports string keys. When you serialize a dictionary with non-string keys, they are automatically converted to strings. This means a round-trip conversion does not preserve the original key types:
import json
original = {1: "one", 2: "two", 3: "three"}
print(f"Original keys: {list(original.keys())}")
print(f"Key types: {[type(k) for k in original.keys()]}")
# Round-trip through JSON
json_string = json.dumps(original)
restored = json.loads(json_string)
print(f"\nRestored keys: {list(restored.keys())}")
print(f"Key types: {[type(k) for k in restored.keys()]}")
# This lookup now fails
try:
print(restored[1])
except KeyError:
print("\nKeyError: integer key 1 no longer exists")
print(f"Must use string key: {restored['1']}")
Output:
Original keys: [1, 2, 3]
Key types: [<class 'int'>, <class 'int'>, <class 'int'>]
Restored keys: ['1', '2', '3']
Key types: [<class 'str'>, <class 'str'>, <class 'str'>]
KeyError: integer key 1 no longer exists
Must use string key: one
If your code relies on non-string dictionary keys, be aware that serializing to JSON and back will silently change them to strings. This is a common source of bugs in applications that store data as JSON and then try to look up values using the original key types.
Type Mapping Reference
| Python Type | JSON Type | Notes |
|---|---|---|
dict | object | Keys are converted to strings |
list, tuple | array | Tuples become arrays (lists on round-trip) |
str | string | Must use double quotes in JSON |
int, float | number | JSON makes no distinction between int and float |
True | true | Lowercase in JSON |
False | false | Lowercase in JSON |
None | null | Different keyword |
Feature Comparison
| Feature | Dictionary | JSON |
|---|---|---|
| What it is | In-memory Python object | Text string for data exchange |
| Key types | Any hashable type | Strings only |
| Value types | Any Python object | Strings, numbers, booleans, null, arrays, objects |
| Quote style | Single or double | Double quotes only |
| Trailing commas | Allowed | Invalid |
| Boolean format | True / False | true / false |
| Null format | None | null |
| Primary purpose | Program logic and data manipulation | Data interchange between systems |
Summary
A Python dictionary is an in-memory object that you manipulate directly in your code. JSON is a text string that you send over networks, store in files, or use to exchange data between different systems and programming languages.
- You cannot "parse" a dictionary because it is already a live Python object.
- You parse JSON strings into dictionaries using
json.loads(), and convert dictionaries into JSON strings usingjson.dumps().
When converting between the two, be aware of the automatic type transformations:
TruebecomestrueNonebecomesnull- integer keys become string keys
- tuples become arrays
Understanding these differences prevents confusion and subtle bugs when working with APIs, configuration files, and data storage.