Last updated: Apr 8, 2024
Reading timeยท4 min
The Python "TypeError: Object of type set is not JSON serializable" occurs
when we try to convert a set
object to a JSON string.
To solve the error, convert the set
to a list before serializing it to JSON,
e.g. json.dumps(list(my_set))
.
Here is an example of how the error occurs.
import json my_set = {'a', 'b', 'c', 'd'} # โ๏ธ TypeError: Object of type set is not JSON serializable json_str = json.dumps(my_set)
We tried passing a set
object to the json.dumps()
method but the method
doesn't handle set
objects by default
set
object to a list
to solve the errorTo solve the error, use the built-in list()
class to convert the set
to a list
before serializing it.
import json my_set = {'a', 'b', 'c', 'd'} json_str = json.dumps(list(my_set)) print(json_str) # '["b", "c", "a", "d"]' print(type(json_str)) # <class 'str'>
The default JSON encoder handles list
values, so we can use a native Python
list
instead of a set
when serializing to JSON.
The json.dumps() method converts a Python object to a JSON formatted string.
SetEncoder
class to solve the errorAlternatively, you can extend from the JSONEncoder
class and handle the
conversions in a default
method.
import json class SetEncoder(json.JSONEncoder): def default(self, obj): if isinstance(obj, set): return list(obj) return json.JSONEncoder.default(self, obj) my_set = {'a', 'b', 'c', 'd'} json_str = json.dumps(my_set, cls=SetEncoder) print(json_str) # ๐๏ธ '["b", "c", "a", "d"]' print(type(json_str)) # ๐๏ธ <class 'str'>
We extended from the JSONEncoder class.
The JSONEncoder
class supports the following objects and types by default.
Python | JSON |
---|---|
dict | object |
list, tuple | array |
str | string |
int, float, int and float derived Enums | number |
True | true |
False | false |
None | null |
Notice that the JSONEncoder
class doesn't support set
to JSON conversion by
default.
We can handle this by extending from the class and implementing a default()
method that returns a serializable object.
import json class SetEncoder(json.JSONEncoder): def default(self, obj): if isinstance(obj, set): return list(obj) return json.JSONEncoder.default(self, obj)
If the passed-in value is a set
, we convert it to a list
and return the
result.
The isinstance() function
returns True
if the passed-in object is an instance or a subclass of the
passed-in class.
To use a custom JSONEncoder
, specify it with the cls
keyword argument in
your call to the json.dumps()
method.
import json class SetEncoder(json.JSONEncoder): def default(self, obj): if isinstance(obj, set): return list(obj) return json.JSONEncoder.default(self, obj) my_set = {'a', 'b', 'c', 'd'} # โ Pass cls keyword argument json_str = json.dumps(my_set, cls=SetEncoder) print(json_str) # ๐๏ธ '["b", "c", "a", "d"]' print(type(json_str)) # ๐๏ธ <class 'str'>
If you don't provide the cls
kwarg, the default JSONEncoder
is used.
default
keyword argument to solve the errorYou can also use the default
keyword argument in the call to the
json.dumps()
method.
import json my_set = {'a', 'b', 'c', 'd'} json_str = json.dumps(my_set, default=list) print(json_str) # ["c", "d", "b", "a"] print(type(json_str)) # <class 'str'>
The json.dumps method converts a Python object to a JSON formatted string.
default
keyword argument can be set to a function that gets called for objects that can't otherwise be serialized.We simply convert the set
object to a list by passing it to the list
class.
You can also define a custom JSON serializer function.
import json my_set = {'a', 'b', 'c', 'd'} def json_serializer(value): if isinstance(value, set): return list(value) return value json_str = json.dumps(my_set, default=json_serializer) print(json_str) # ["a", "d", "b", "c"] print(type(json_str)) # <class 'str'>
We set the default
keyword argument to the custom json_serializer
function.
The function uses the isinstance()
function to check if the value is a set
.
If the value is a set
, we convert it to a list and return the result.
Otherwise, the value is returned as is.
simplejson
module to solve the errorAn alternative way to solve the error is to use the simplejson module.
You can install the module by running the following command from your terminal.
pip install simplejson # ๐๏ธ or pip3 pip3 install simplejson
Now you can use the simplejson.dumps()
method to serialize the set
object.
import simplejson as json my_set = {'a', 'b', 'c', 'd'} json_str = json.dumps(my_set, iterable_as_array=True) print(json_str) # ["b", "c", "d", "a"] print(type(json_str)) # <class 'str'>
Notice that we imported simplejson
and aliased it to json
.
When the iterable_as_array
keyword argument is set to True
, objects that
cannot be converted to JSON by default but implement the __iter__()
method get
encoded as a JSON array.
This is exactly what we need to convert a set
to JSON.
I've also written an article on how to create a Set from user input.