TypeError Object of type dict_items is not JSON serializable

avatar

Borislav Hadzhiev

Wed Apr 20 20222 min read

banner

Photo by Resa Cahya

TypeError Object of type dict_items is not JSON serializable #

The Python "TypeError: Object of type dict_items is not JSON serializable" occurs when we try to convert a dict_items object to JSON. To solve the error, convert the dict to JSON or pass the dict_items object to the list() class before the conversion to JSON.

Here is an example of how the error occurs.

main.py
import json my_dict = {'name': 'Alice', 'age': 30} # ⛔️ TypeError: Object of type dict_items is not JSON serializable json_str = json.dumps(my_dict.items())

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

To solve the error, either remove the call to the items() method and serialize the dict object to JSON or, pass the dict_items object to the list() class before serializing it.

main.py
import json my_dict = {'name': 'Alice', 'age': 30} # ✅ convert to list json_str = json.dumps(list(my_dict.items())) print(json_str) # 👉️ '[["name", "Alice"], ["age", 30]]' print(type(json_str)) # 👉️ <class 'str'>

The example converts the dict_items object to a list when serializing to JSON.

Alternatively, you can serialize the dict by removing the call to the items() method.

main.py
import json my_dict = {'name': 'Alice', 'age': 30} # ✅ serialize the dict json_str = json.dumps(my_dict) print(json_str) # 👉️ '{"name": "Alice", "age": 30}' print(type(json_str)) # 👉️ <class 'str'>

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

The dict.items method returns a new view of the dictionary's items ((key, value) pairs).

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

main.py
import json from collections import abc class DictItemsEncoder(json.JSONEncoder): def default(self, obj): if isinstance(obj, abc.ItemsView): return list(obj) return json.JSONEncoder.default(self, obj) my_dict = {'name': 'Alice', 'age': 30} json_str = json.dumps(my_dict.items(), cls=DictItemsEncoder) print(json_str) # 👉️ '[["name", "Alice"], ["age", 30]]' print(type(json_str)) # 👉️ <class 'str'>

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 dict_items 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 from collections import abc class DictItemsEncoder(json.JSONEncoder): def default(self, obj): if isinstance(obj, abc.ItemsView): return list(obj) return json.JSONEncoder.default(self, obj)

If the passed in value is a dict_items object, 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 classes' 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 from collections import abc class DictItemsEncoder(json.JSONEncoder): def default(self, obj): if isinstance(obj, abc.ItemsView): return list(obj) return json.JSONEncoder.default(self, obj) my_dict = {'name': 'Alice', 'age': 30} # ✅ pass cls kwarg json_str = json.dumps(my_dict.items(), cls=DictItemsEncoder) print(json_str) # 👉️ '[["name", "Alice"], ["age", 30]]' print(type(json_str)) # 👉️ <class 'str'>

If you don't provide the cls kwarg, the default JSONEncoder is used.

Use the search field on my Home Page to filter through my more than 1,000 articles.