How to Solve Python TypeError: object of type ‘filter’ has no len()

by | Programming, Python, Tips

This error occurs when you try to pass a filter object to a len() method call. The filter() object is an iterator containing the items in the specified iterable that satisfy the condition of the function passed to the filter() function. In Python, iterators do not have a length.

We can solve the error by converting the filter object to a list object using the built-in list() method.

For example,

numbers = [2, 3, 4, 5, 6, 7, 9]

even_numbers = list(filter(lambda x: x % 2 == 0 , numbers))

print(len(even_numbers))

This tutorial will go through how to solve the error with code examples.


TypeError: object of type ‘filter’ has no len()

We raise a Python TypeError when attempting to perform an illegal operation for a specific type. In this case, the type is filter.

The part ‘has no len()‘ tells us the map object does not have a length, and therefore len() is an illegal operation for the filter object.

Retrieving the length of an object is only suitable for iterable objects, like a list or a tuple. A filter object is an iterator containing the items in the specified iterable that satisfy the condition of the function passed to the filter() function.

All iterators have the __iter__ dunder method, which we can check by passing the iterator to the dir() method:

numbers = [2, 3, 4, 5, 6, 7, 9]

even_numbers = filter(lambda x: x % 2 == 0 , numbers)

print('__iter__' in dir(even_numbers))
True

The len() method implicitly calls the dunder method __len__() which returns a positive integer representing the length of the object on which it is called. All iterable objects have __len__ as an attribute. Let’s check if __len__ is in the list of attributes for the filter object and the list object using the built-in dir() method.

numbers = [2, 3, 4, 5, 6, 7, 9]

even_numbers = filter(lambda x: x % 2 == 0 , numbers)

print(type(even_numbers))

print('__len__' in dir(even_numbers))
<class 'filter'>
False

We can see that __len__ is not present in the attributes of the filter object.

lst = ["Einstein", "Feynman", "Dirac"]

print(type(lst))

print('__len__' in dir(lst))
<class 'list'>
True

We can see that __len__ is present in the attributes of the list object.

Example

Let’s look at an example of trying to get the length of a filter object. First, we will create a function to use as the filtering function argument.

def sq_root(number):

    sq_root = number ** 0.5

    if sq_root < 10:

        return True

    else:

        return False

The above function calculates the square root of a number and returns True if the square root value is less than 10. Otherwise, the function returns False.

Next, we will use the filter() function to filter values in a list of integers. The filter function takes a function and a sequence as arguments and returns an iterator containing the items for which the function returns True.

If we pass None instead of a function to filter() then all of the items in the sequence that evaluate to False are removed.

The syntax for the filter() function is:

filter(function or None, iterable) -> filter object
numbers = [100, 49, 81, 147, 13, 200, 30]

filtered_numbers = filter(sq_root, numbers)

Next, we will try to get the length of the filter object and print it to the console.

print(len(filtered_numbers))
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
Input In [12], in <cell line: 1>()
----> 1 print(len(filtered_numbers))

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

The error occurs because the filter object is an iterator and does not have a length.

Solution

We can solve the error by converting the filter object to a list, which is an iterable data type. We can convert a filter object to a list using the built-in list() method. Let’s look at the revised code:

def sq_root(number):

    sq_root = number ** 0.5

    if sq_root < 10:

        return True

    else:

        return False

numbers = [100, 49, 81, 147, 13, 200, 30]

filtered_numbers = list(filter(sq_root, numbers))

print(len(filtered_numbers))

Let’s run the code to get the length of the list:

4

We successfully converted the filter object to a list and then used the len() method to get the length of the list.

Summary

Congratulations on reading to the end of this tutorial!

For further reading on the has no len() TypeErrors, go to the article:

To learn more about Python for data science and machine learning, go to the online courses page on Python, which provides the best, easy-to-use online courses.

Research Scientist at Moogsoft | + posts

Suf is a research scientist at Moogsoft, specializing in Natural Language Processing and Complex Networks. Previously he was a Postdoctoral Research Fellow in Data Science working on adaptations of cutting-edge physics analysis techniques to data-intensive problems in industry. In another life, he was an experimental particle physicist working on the ATLAS Experiment of the Large Hadron Collider. His passion is to share his experience as an academic moving into industry while continuing to pursue research. Find out more about the creator of the Research Scientist Pod here and sign up to the mailing list here!