You are here because when you try to dump or encode Python set into JSON, you received an error, TypeError: Object of type set is not JSON serializable
.
The built-in json module of Python can only handle Python primitives types that have a direct JSON equivalent. i.e., The fundamental problem is that the JSON encoder json.dump() and json.dumps() only knows how to serialize the basic types by default (e.g., dictionary, lists, strings, numbers, None, etc.). To solve this, we need to build a custom encoder to make set
JSON serializable.
Further Reading:
- Solve Python JSON Exercise to practice Python JSON skills
In this article, we will see how to JSON Serialize Set. There are multiple ways to accomplish this.
Use the jsonpickle module to make Python set JSON serializable
jsonpickle is a Python library designed to work with complex Python Objects. You can use jsonpickle for serialization complex Python objects into JSON. Also, and deserialization from JSON to complex Python objects. jsonpickle allows more complex data structures to be serialized to JSON. jsonpickle is highly configurable and extendable.
Steps:
- Install jsonpickle using pip.
pip install jsonpickle
- Execute
jsonpickle.encode(object)
to serialize custom Python Object.
You can refer to Jsonpickle Documentation for more detail. Let’s see the jsonpickle example to make a set
JSON serializable.
import json
import jsonpickle
from json import JSONEncoder
sampleSet = {25, 45, 65, 85}
print("Encode set into JSON using jsonpickle")
sampleJson = jsonpickle.encode(sampleSet)
print(sampleJson)
# Pass sampleJson to json.dump() if you want to write it in file
print("Decode JSON into set using jsonpickle")
decodedSet = jsonpickle.decode(sampleJson)
print(decodedSet)
# to check if we got set after decoding
decodedSet.add(95)
print(decodedSet)
Output:
Encode set into JSON using jsonpickle {"py/set": [65, 25, 85, 45]} Decode JSON into set using jsonpickle {65, 45, 85, 25} {65, 45, 85, 25, 95}
Use custom JSON Encoder to make Python set JSON serializable
Let’ see how to write custom encoder to JSON serializable Python set. Python json module provides a JSONEncoder
to encode python types into JSON. We can extend by implementing its default()
method that can JSON serializable set.
In default()
method we will convert set
into list
using list(setObj)
The json.dump() and json.dumps() methods of the json module has a cls
kwarg
. Using this argument, you can pass a custom JSON Encoder, which tells dump or dumps method how to encode set
into JSON formatted data.
JSONEncoder class has a default()
method which will be used when we execute JSONEncoder.encode(object)
. This method converts only basic types into JSON.
Your custom JSONEncoder subclass will override the default()
method to serialize additional types. Specify it with the cls
kwarg in json.dumps()
method; otherwise, default JSONEncoder is used. Example: json.dumps(cls=CustomEncoder)
.
import json
from json import JSONEncoder
# subclass JSONEncoder
class setEncoder(JSONEncoder):
def default(self, obj):
return list(obj)
sampleSet = {25, 45, 65, 85}
print("Encode Set and Printing to check how it will look like")
print(setEncoder().encode(sampleSet))
print("Encode Set nto JSON formatted Data using custom JSONEncoder")
jsonData = json.dumps(sampleSet, indent=4, cls=setEncoder)
print(jsonData)
# Let's load it using the load method to check if we can decode it or not.
setObj = json.loads(jsonData, object_hook=customSetDecoder)
print("Decode JSON formatted Data")
print(setObj)
Output:
Encode Set and Printing to check how it will look like [65, 25, 85, 45] Encode Set nto JSON formatted Data using custom JSONEncoder [ 65, 25, 85, 45 ] Decode JSON formatted Data [65, 25, 85, 45]
So What Do You Think?
I want to hear from you. What do you think of this article? Or maybe I missed one of the ways to JSON serialize Python set, Either way, let me know by leaving a comment below.
Also, try to solve the Python JSON Exercise to have a better understanding of Working with JSON Data in Python.
The second example seems to be missing a definition of `customSetDecoder`.