How to Resolve "TypeError: Object of type set is not JSON serializable" in Python
The TypeError: Object of type set is not JSON serializable error occurs when you try to serialize a Python set object directly using the json.dumps() method. Sets are not part of the standard JSON data types.
This guide explains why this error occurs and provides the correct solutions, including converting sets to lists, creating custom encoders, and using the simplejson library as an alternative.
Understanding the Error: JSON and Sets
JSON (JavaScript Object Notation) is a lightweight data-interchange format. It supports basic data types like:
- Objects (similar to Python dictionaries)
- Arrays (similar to Python lists)
- Strings
- Numbers (integers and floating-point)
- Booleans (
trueandfalse) null
Sets are not directly supported in the JSON standard. Therefore, Python's built-in json module doesn't know how to serialize a set by default.
import json
my_set = {'a', 'b', 'c', 'd'}
# ⛔️ TypeError: Object of type set is not JSON serializable
# json_str = json.dumps(my_set)
Solution 1: Convert the Set to a List (Recommended)
The simplest and most common solution is to convert the set to a list before serialization:
import json
my_set = {'a', 'b', 'c', 'd'}
json_str = json.dumps(list(my_set)) # Convert to list before serializing
print(json_str) # Output: ["a", "c", "d", "b"] (order may vary)
print(type(json_str)) # Output: <class 'str'>
list(my_set): Creates a list containing all the elements of the set. Note: The order of elements in a set is arbitrary, so the order in the list might not match the order you added elements.json.dumps(...): Serializes the list to a JSON array string.
This is the best approach in most situations because lists are directly supported by JSON, and it's very concise.
Solution 2: Custom JSON Encoder (for Complex Cases)
If you need more control over how sets (and potentially other custom types) are serialized, you can create a custom JSONEncoder subclass:
import json
class SetEncoder(json.JSONEncoder):
def default(self, obj):
if isinstance(obj, set):
return list(obj) # Convert set to list
return super().default(obj) # Fallback to default for other types
my_set = {'a', 'b', 'c', 'd'}
json_str = json.dumps(my_set, cls=SetEncoder) # Pass the encoder class
print(json_str) # Output: ["a", "b", "d", "c"] (order may vary)
class SetEncoder(json.JSONEncoder):: We create a subclass ofjson.JSONEncoder.def default(self, obj):: This method is called wheneverjson.dumps()encounters an object it doesn't know how to serialize.if isinstance(obj, set):: We check if the object is a set.return list(obj): If it's a set, we convert it to a list and return it.return super().default(obj): If it's not a set, we call thedefaultmethod of the parent class (JSONEncoder). This handles the standard JSON types and raises aTypeErrorif it encounters an unsupported type. This is important for handling other non-serializable types correctly.
- To use the custom encoder, the
clsparameter is passed to thejson.dumpsmethod, setting it to our custom encoder.
Solution 3: Using simplejson (with iterable_as_array)
The simplejson library is a fast, widely-used alternative to the built-in json module. It offers an option to treat all iterables (including sets) as arrays:
# Install simplejson first: pip install simplejson
import simplejson as json # Use 'as json' for convenience
my_set = {'a', 'b', 'c', 'd'}
json_str = json.dumps(my_set, iterable_as_array=True) # Serialize set as array
print(json_str) # Output: ["a", "b", "c", "d"] (order may vary)
iterable_as_array=True: This tellssimplejsonto treat any iterable object (including sets) as if it were a list/array during serialization.
While this works, it's generally better to be explicit and convert your sets to lists using list(my_set) before using the standard json module. This improves code clarity and avoids relying on a specific feature of simplejson.
Using the default Argument (Less Flexible)
You can pass the list constructor to the default argument of the json.dumps() method:
import json
my_set = {'a', 'b', 'c', 'd'}
json_str = json.dumps(my_set, default=list)
print(json_str)
- The
defaultargument is a function that returns a serializable object. - This is less flexible than using a custom
JSONEncoderbecause it requires you to create a new function every time you want to handle different classes.
Conclusion
The TypeError: Object of type set is not JSON serializable error occurs because JSON doesn't have a native set data type.
- The best solution is to convert the set to a list before serializing it with
json.dumps(). - For more complex scenarios where you need to serialize other custom types along with sets, a custom
JSONEncodersubclass gives you fine-grained control.simplejsonwithiterable_as_array=Trueprovides an alternative, but explicitly converting to a list is generally preferred for clarity and compatibility. - Avoid using the
defaultargument to thejson.dumpsfunction for general use cases.