Borislav Hadzhiev
Wed Apr 20 2022·2 min read
Photo by Rakesh Kumar Swain
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))
.
Here is an example of how the error occurs.
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.
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.
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.
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.
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.
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.
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.
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.