Select Page

How to Solve Python TypeError: cannot unpack non-iterable bool object

by | Programming, Python, Tips

In Python, you can unpack iterable objects and assign their elements to multiple variables in the order they appear. If you try to unpack a Boolean, you will throw the error TypeError: cannot unpack non-iterable bool object. A Boolean is not a sequence that we can loop over.

This error commonly occurs when trying to unpack a Boolean returned by a function.

We can solve this error by ensuring the function returns an iterable object, like a tuple. For example,

def name_checker(prefix):

    lst = ['hexagon', 'octagon', 'hexagram', 'pentagon', 'dodecahedron']

    filtered = list(filter(lambda x: x.startswith(prefix), lst))

    if len(filtered) > 0:

        return True, filtered
    else:
        return False, filtered

bool_val, filtered_lst = name_checker('hex')

print(bool_val)

print(filtered_lst)

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


TypeError: cannot unpack non-iterable bool object

TypeError occurs in Python when you perform an illegal operation for a specific data type. . Unpacking is only suitable for iterable objects.

What is an Iterable Object in Python?

An iterable is an object that can be “iterated over“, for example in a for loop. In terms of dunder methods under the hood, an object can be iterated over with “for” if it implements __iter__() or __getitem__().

An iterator returns the next value in the iterable object. An iterable generates an iterator when it is passed to the iter() method.

In terms of dunder methods under the hood, an iterator is an object that implements the __next__() method.

A for loop automatically calls the iter() method to get an iterator and then calls next over and over until it reaches the end of the iterable object.

Unpacking requires an iteration in order to assign values to variables in order, and as such requires iterable objects.

What is Unpacking in Python?

Unpacking is the process of splitting packed values into individual elements. The packed values can be a string, list, tuple, set or dictionary. During unpacking, the elements on the right-hand side of the statement are split into the values on the left-hand side based on their relative positions. Let’s look at the unpacking syntax with an example:

values = [10, 20, 30]

x, y, z = values

print(f'x: {x}, y: {y}, z: {z}')

The above code assigns the integer values in the value list to three separate variables. The value of x is 10, y is 20, and the value of z is 30. Let’s run the code to get the result:

x: 10, y: 20, z: 30

We can also unpack sets and dictionaries. Dictionaries are only ordered for Python version 3.7 and above but are unordered for 3.6 and below. Generally, it is not recommended to unpack unordered collections of elements as there is no guarantee of the order of the unpacked elements.

Example

Let’s look at an example of trying to unpack a bool object. First, we will define a function which checks for shapes that start with a specific prefix in a list of strings.

def name_checker(prefix):

    # Define list of shapes

    lst = ['hexagon', 'octagon', 'hexagram', 'pentagon', 'dodecahedron']

    # Filter function to find strings that start with the specified prefix 

    filtered = list(filter(lambda x: x.startswith(prefix), lst))
    
    # If found at least one shape, return True and the list

    if len(filtered) > 0:

        return True, filtered

    # Otherwise return False

    else:

        return False

The function uses the filter function to filter out strings that start with the specified prefix argument.

If the number of filtered strings is greater than 0, the function returns True and the list of filtered strings. Otherwise, the function returns False.

Next, we will try to unpack the objects returned by the name_checker function call and print them to the console.

bool_val, filtered_lst = name_checker('hex')
print(bool_val)
print(filtered_lst)

Let’s run the code to get the result:

True
['hexagon', 'hexagram']

In this case, there are two strings that start with the prefix “hex”. Therefore, the function returns True and the list of filtered strings.

Let’s try to do a similar call, but this time with a prefix that we know does not exist in the list of strings.

bool_val, filtered_lst = name_checker('non')
print(bool_val)
print(filtered_lst)

Let’s run the code to see the result:

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
Input In [75], in <cell line: 1>()
----> 1 bool_val, filtered_lst = name_checker('non')
      2 print(bool_val)
      3 print(filtered_lst)

TypeError: cannot unpack non-iterable bool object

The error occurs because the number of filtered strings is 0 then the function returns False. Therefore, when we try to perform unpacking, we are unpacking False, which is a bool object and cannot be unpacked.

Solution

We can solve this error by ensuring that the function returns a uniform number of objects for the two outcomes of the if-else statement. Let’s look at the revised code:

def name_checker(prefix):

    lst = ['hexagon', 'octagon', 'hexagram', 'pentagon', 'dodecahedron']

    filtered = list(filter(lambda x: x.startswith(prefix), lst))

    if len(filtered) > 0:

        return True, filtered
    else:
        return False, filtered

In the above code, we changed the else code block to return both False and the filtered list of strings as a tuple.

bool_val, filtered_lst = name_checker('non')

print(bool_val)

print(filtered_lst)

Let’s run the code to get the result:

False
[]

We successfully returned False and the empty list as there were no strings that started with ‘non‘ in the list.

Summary

Congratulations on reading to the end of this tutorial!

For more reading on cannot unpack non-iterable object errors, go to the articles:

Go to the online courses page on Python to learn more about Python for data science and machine learning.

Have fun and happy researching!