TypeError: object of type 'filter' has no len() in Python

avatar

Borislav Hadzhiev

Wed Apr 20 20222 min read

TypeError: object of type 'filter' has no len() in Python #

The Python "TypeError: object of type 'filter' has no len()" occurs when we pass a filter object to the len() function. To solve the error, convert the filter object to a list before using the len function, e.g. len(list(my_filter)).

typeerror object of type filter has no len

Here is an example of how the error occurs.

main.py
my_list = [2, 4, 6, 8] result = filter(lambda num: num > 4, my_list) # ⛔️ TypeError: object of type 'filter' has no len() print(len(result))

We can't pass a filter object to the len() function but we can convert it to a list and get the length of the list.

main.py
my_list = [2, 4, 6, 8] # 👇️ convert to list result = list(filter(lambda num: num > 4, my_list)) print(result) # 👉️ [6, 8] print(len(result)) # 👉️ 2

The list class takes an iterable and returns a list object.

Alternatively, you could use a list comprehension.

main.py
my_list = [2, 4, 6, 8] # 👇️ using list comprehension instead result = [num for num in my_list if num > 4] print(result) # 👉️ [6, 8] print(len(result)) # 👉️ 2

Note that passing a filter object to the list class exhausts the iterator.

main.py
my_list = [2, 4, 6, 8] result = filter(lambda num: num > 4, my_list) l1 = list(result) print(l1) # 👉️ [6, 8] l2 = list(result) print(l2) # 👉️ []

So if you convert a filter object to a list, do it directly and not in multiple places.

The filter function takes a function and an iterable as arguments and constructs an iterator from the elements of the iterable for which the function returns a truthy value.

If you pass None for the function argument, all falsy elements of the iterable are removed.

When we pass an object to the len() function, the object's __len__() method is called.

You can use the dir() function to print an object's attributes and look for the __len__ attribute.

main.py
my_list = [2, 4, 6, 8] result = filter(lambda num: num > 4, my_list) # 👇️ ['__class__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', # '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', # '__iter__', '__le__', '__lt__', ...] print(dir(result))

Or you can check using a try/except statement.

main.py
my_list = [2, 4, 6, 8] result = filter(lambda num: num > 4, my_list) try: print(result.__len__) except AttributeError: # 👇️ this runs print('object has no attribute __len__')

We try to access the object's __len__ attribute in the try block and if an AttributeError is raised, we know the object doesn't have a __len__ attribute and cannot be passed to the len() function.

The len() function returns the length (the number of items) of an object.

main.py
my_list = ['apple', 'banana', 'kiwi'] result = len(my_list) print(result) # 👉️ 3

The argument the function takes may be a sequence (a string, tuple, list, range or bytes) or a collection (a dictionary, set, or frozen set).

If you aren't sure what type a variable stores, use the built-in type() class.

main.py
my_list = [2, 4, 6, 8] print(type(my_list)) # 👉️ <class 'list'> print(isinstance(my_list, list)) # 👉️ True result = filter(lambda num: num > 4, my_list) print(type(result)) # 👉️ <class 'filter'> print(isinstance(result, filter)) # 👉️ True

The type class returns the type of an object.

The isinstance function returns True if the passed in object is an instance or a subclass of the passed in class.

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