TypeError: Object of type set is not JSON serializable

avatar
Borislav Hadzhiev

Last updated: Jan 30, 2023
4 min

banner

# TypeError: Object of type set is not JSON serializable

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.

main.py
import json my_set = {'a', 'b', 'c', 'd'} # โ›”๏ธ TypeError: Object of type set is not JSON serializable json_str = json.dumps(my_set)

typeerror object of type set is not json serializable

We tried passing a set object to the json.dumps() method but the method doesn't handle set objects by default

# Convert the set object to a list to solve the error

To solve the error, use the built-in list() class to convert the set to a list before serializing it.

main.py
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'>

convert set to list to solve the error

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.

# Create a custom SetEncoder class to solve the error

Alternatively, you can extend from the JSONEncoder class and handle the conversions in a default method.

main.py
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'>

create custom setencoder class to solve the error

We extended from the JSONEncoder class.

The JSONEncoder class supports the following objects and types by default.

PythonJSON
dictobject
list, tuplearray
strstring
int, float, int and float derived Enumsnumber
Truetrue
Falsefalse
Nonenull

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.

main.py
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.

In all other cases, we let the base class's default method do the serialization.

To use a custom JSONEncoder, specify it with the cls keyword argument in your call to the json.dumps() method.

main.py
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.

# Using the default keyword argument to solve the error

You can also use the default keyword argument in the call to the json.dumps() method.

main.py
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'>

using default keyword argument to solve error

The json.dumps method converts a Python object to a JSON formatted string.

The 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.

main.py
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'>

define custom json serializer function to solve the error

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.

# Using the simplejson module to solve the error

An 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.

shell
pip install simplejson # ๐Ÿ‘‡๏ธ or pip3 pip3 install simplejson

Now you can use the simplejson.dumps() method to serialize the set object.

main.py
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.

I wrote a book in which I share everything I know about how to become a better, more efficient programmer.
book cover
You can use the search field on my Home Page to filter through all of my articles.

Copyright ยฉ 2024 Borislav Hadzhiev