Computer >> Computer tutorials >  >> Programming >> Python

Python TypeError: ‘NoneType’ object is not iterable Solution

With Python, you can only iterate over an object if that object has a value. This is because iterable objects only have a next item which can be accessed if their value is not equal to None. If you try to iterate over a None object, you encounter the TypeError: ‘NoneType’ object is not iterable error.

In this guide, we talk about what this error means and why you may encounter it. We walk through an example to help you solve how to solve this common Python error.

TypeError: ‘NoneType’ object is not iterable

For an object to be iterable, it must contain a value. A None value is not iterable because it does not contain any objects. None represents a null value.

There is a difference between a None object and an empty iterable. This error is not raised if you have any empty list or a string.

This is because lists and strings have an iterable data type. When the Python interpreter encounters an empty list, it does not iterate over it because there are no values. Python cannot iterate over a None value so the interpreter returns an error.

This error is common when you declare a function and forget to return a value.

An Example Scenario

Let’s write a program that takes a list of student names and filters out those that begin with “E”. We’ll print those values to the console.

Start by defining a function that filters out the students’ names:

81% of participants stated they felt more confident about their tech job prospects after attending a bootcamp. Get matched to a bootcamp today.

The average bootcamp grad spent less than six months in career transition, from starting a bootcamp to finding their first job.

def filter_students(class_names):
	new_class_names = []
	for c in class_names:
		if c.startswith("E"):
			new_class_names.append(c)

This function loops through every item in the “class_names” list using a for loop. For each item, our loop checks if the item begins with the letter “E”. If it does, that name is added to the “new_class_names” list.

Next, write a function that goes through our new list and prints out each value to the console:

def show_students(class_names):
	for c in class_names:
		print(c)

Here, we declare a list of students through which our program should search. We pass this list of students through our filter_students function:

students = ["Elena", "Peter", "Chad", "Sam"]
students_e_name = filter_students(students)

This code executes the filter_students function which finds all the students whose names start with “E”. The list of students whose names begin with “E” is called students_e_name. Next, we call our show_students function to show the new list of students:

show_students(students_e_name)

Let’s run our code and see what happens:

Traceback (most recent call last):
  File "main.py", line 14, in <module>
	show_students(students_e_name)
  File "main.py", line 8, in show_students
	for c in class_names:
TypeError: 'NoneType' object is not iterable

Our code returns an error message.

The Solution

When we try to iterate over the variable class_names in the show_students function, our code detects a None value and raises an error. This is because the value we have passed as “class_names” is None.

This error is caused because our filter_students function does not return a value. When we assign the result of the filter_students function to the variable students_e_name, the value None is set.

To solve this error, we have to return a value in our filter_students function:

def filter_students(class_names):
	new_class_names = []
	for c in class_names:
		if c.startswith("E"):
			new_class_names.append(c)
      # We have added a return statement here
	return new_class_names
        
def show_students(class_names):
	for c in class_names:
		print(c)
    
students = ["Elena", "Peter", "Chad", "Sam"]
students_e_name = filter_students(students)

show_students(students_e_name)

This code returns the value of new_class_names back to the main program.

Let’s run our code to see if it works:

Elena

Our code now successfully prints out the names of the students whose names begin with “E”.

Avoiding the NoneType Exception

Technically, you can avoid the NoneType exception by checking if a value is equal to None before you iterate over that value. Consider the following code:

def filter_students(class_names):
	new_class_names = []
	for c in class_names:
		if c.startswith("E"):
			new_class_names.append(c)
	return new_class_names

def show_students(class_names):
	if class_names is not None:
		for c in class_names:
			print(c)
            
students = ["Elena", "Peter", "Chad", "Sam"]
students_e_name = filter_students(students)

show_students(students_e_name)

The “show_students()” function executes successfully because we check if class_names is a None value before we try to iterate over it. This is not a best practice in most cases because the cause of a NoneType error can be a problem somewhere else in your code.

If we add in the “is not None” check into our full program, we don’t know we missed a return statement in another function. That’s why if you see this error, you are best to accept the exception rather than handle it using an “is not None” check.



Conclusion

The TypeError: ‘NoneType’ object is not iterable error is raised when you try to iterate over an object whose value is equal to None.

To solve this error, make sure that any values that you try to iterate over have been assigned an iterable object, like a string or a list. In our example, we forgot to add a “return” statement to a function. This made the function return None instead of a list.

Now you’re ready to solve this common Python error in your own code.