Borislav Hadzhiev
Wed Apr 20 2022·2 min read
Photo by Yasin Hoşgör
The Python "TypeError: Object of type map is not JSON serializable" occurs
when we try to convert a map
object to a JSON string. To solve the error,
convert the map
to a list before serializing it to JSON, e.g.
json.dumps(list(my_map))
.
Here is an example of how the error occurs.
import json my_list = [1, 2, 3, 4] result = map(lambda x: x + 1, my_list) # ⛔️ TypeError: Object of type map is not JSON serializable json_str = json.dumps(result)
We tried passing a map
object to the json.dumps()
method but the method
doesn't handle map
objects by default
To solve the error, use the built-in list()
class to convert he map
to a
list
before serializing it.
import json my_list = [1, 2, 3, 4] result = map(lambda x: x + 1, my_list) # ✅ convert to list json_str = json.dumps(list(result)) print(json_str) # 👉️ '[2, 3, 4, 5]' print(type(json_str)) # 👉️ <class 'str'>
The default JSON encoder handles list
values, so we can use a native Python
list
instead of a map
when serializing to JSON.
The json.dumps method converts a Python object to a JSON formatted string.
Alternatively, you can extend from the JSONEncoder
class and handle the
conversions in a default
method.
import json class MapEncoder(json.JSONEncoder): def default(self, obj): if isinstance(obj, map): return list(obj) return json.JSONEncoder.default(self, obj) my_list = [1, 2, 3, 4] result = map(lambda x: x + 1, my_list) json_str = json.dumps(result, cls=MapEncoder) print(json_str) # 👉️ [2, 3, 4, 5] 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 map
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 MapEncoder(json.JSONEncoder): def default(self, obj): if isinstance(obj, map): return list(obj) return json.JSONEncoder.default(self, obj)
If the passed in value is a map
, 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 MapEncoder(json.JSONEncoder): def default(self, obj): if isinstance(obj, map): return list(obj) return json.JSONEncoder.default(self, obj) my_list = [1, 2, 3, 4] result = map(lambda x: x + 1, my_list) # ✅ pass cls keyword argument json_str = json.dumps(result, cls=MapEncoder) print(json_str) # 👉️ [2, 3, 4, 5] print(type(json_str)) # 👉️ <class 'str'>
If you don't provide the cls
kwarg, the default JSONEncoder
is used.