Python is a popular and versatile programming language, but like any other language, it can throw errors that can be frustrating to debug. One of the common errors that developers encounter is the “TypeError: ‘NoneType’ object is not iterable.” In this article, we will explore various scenarios where this error can occur and provide practical solutions to help you tackle it effectively.
Understanding the Error: NoneType’ object is not Iterable
The error message “TypeError: ‘NoneType’ object is not iterable” in Python typically occurs when you try to iterate over an object that has a value of None. This error is raised because None is not iterable, meaning you cannot loop through it like you can with lists, tuples, or other iterable objects.
syntax: TypeError: ‘NoneType’ object is not iterable
Causes of “TypeError: ‘NoneType’ object is not iterable”
- Missing Return Statement
- Invalid API Response
- Iterating over a variable with the value None
- None Type error in Classes
- Lambda Functions and NoneType error
Missing Return Statement
One of the most common scenarios leading to this error is a missing return statement in a function. Let’s say we have a function that’s supposed to return a list of numbers, but we forget to include a return statement:
Python3
def
generate_numbers():
numbers
=
[
1
,
2
,
3
,
4
,
5
]
# Missing return statement
result
=
generate_numbers()
for
num
in
result:
print
(num)
Output
---------------------------------------------------------------------------TypeError Traceback (most recent call last)c:\Users\practice.ipynb Cell 1 line 6 3 # Missing return statement 5 result = generate_numbers()----> 6 for num in result: 7 print(num)TypeError: 'NoneType' object is not iterable
In this case, ‘generate_numbers()’ doesn’t return anything, which means it returns None. When we try to iterate over result, we’ll encounter the ‘TypeError’ because we can’t iterate over None.
Solution: Ensure Proper Return
To fix this error, make sure our function returns the expected value. In this example, we should add a return statement to ‘generate_numbers()’:
Python3
def
generate_numbers():
numbers
=
[
1
,
2
,
3
,
4
,
5
]
return
numbers
result
=
generate_numbers()
for
num
in
result:
print
(num)
Output
12345
Now, generate_numbers() returns a list of numbers, and the error is resolved.
Invalid API Response
Another scenario where you might encounter this error is when working with APIs. Let’s say we’re making an API request to fetch data, but the API returns None instead of the expected data:
Python3
import
requests
def
fetch_data():
response
=
requests.get(
"https://api.openweathermap.org/data"
)
if
response.status_code
=
=
200
:
return
response.json()
else
:
return
None
data
=
fetch_data()
for
item
in
data:
print
(item)
Output
---------------------------------------------------------------------------TypeError Traceback (most recent call last)c:\Users\practice.ipynb Cell 2 line 11 8 return None 10 data = fetch_data()---> 11 for item in data: 12 print(item)TypeError: 'NoneType' object is not iterable
If the API request fails or returns None, we’ll get a ‘TypeError’ when trying to iterate over data.
Solution: Check API Response
To handle this situation, we should check the API response before attempting to iterate over it. Here’s an improved version of the code:
Python3
import
requests
def
fetch_data():
response
=
requests.get(
"https://api.openweathermap.org/data"
)
if
response.status_code
=
=
200
:
return
response.json()
else
:
return
[ ]
data
=
fetch_data()
for
item
in
data:
print
(item)
If the status code is not 200, it means there was an issue with the API request. In this case, we return an empty list [] as a placeholder value instead of None. Returning an empty list allows us to avoid the ‘NoneType’ error when attempting to iterate over the response data later in the code.
Iterating over a variable with the value None
This scenario is straightforward and common. It occurs when we attempt to loop (iterate) over a variable that has the value None:
Python3
my_list
=
None
for
item
in
my_list:
print
(item)
Output
---------------------------------------------------------------------------TypeError Traceback (most recent call last)c:\Users\practice.ipynb Cell 3 line 2 1 my_list = None----> 2 for item in my_list: 3 print(item)TypeError: 'NoneType' object is not iterable
In this scenario, the variable ‘my_list’ is set to None. When the for loop attempts to iterate over ‘my_list’, it encounters the TypeError: ‘NoneType’ object is not iterable. This error occurs because None is not an iterable object, and we cannot loop through it.
Solution: Ensuring Iterable presence before looping
To fix this error, we need to ensure that ‘my_list’ contains an iterable object (such as a list, tuple, etc.) before attempting to iterate over it. Adding a check like if my_list is not None before the loop ensures that the code inside the loop only runs if my_list is not None, preventing the ‘NoneType’ error.
Python3
my_list
=
None
if
my_list
is
not
None
:
for
item
in
my_list:
print
(item)
None Type error in Classes
Classes in Python can also encounter ‘NoneType’ errors, especially when working with methods that return None. Consider a class with a method that doesn’t return any value.
Let’s suppose we have a class named ‘Student’. In this class, we want to store a student’s name and their grades. The class has a method called ‘get_grades()’ which, logically, should return the student’s grades. In this situation, a student named ‘Alisha’ is created with a list of grades. The intention is to check if any of Alisha’s grades are above or equal to 90 and print them
Here’s the initial code:
Python3
class
Student:
def
__init__(
self
, name,grade):
self
.name
=
name
self
.grade
=
grade
def
get_grades(
self
):
print
(
self
.grade)
student
=
Student(
"Alisha"
,[
90
,
85
,
88
,
92
])
for
grade
in
student.get_grades():
if
grade>
=
90
:
print
(grade)
Output
---------------------------------------------------------------------------TypeError Traceback (most recent call last)c:\Users\practice.ipynb Cell 4 line 13 8 print(self.grade) 11 student = Student("Alisha",[90,85,88,92])---> 13 for grade in student.get_grades(): 14 if grade>=90: 15 print(grade)TypeError: 'NoneType' object is not iterable
The issue lies in the ‘get_grades()’ method. While it does print the grades, it doesn’t return them. When we try to loop through ‘student.get_grades()’, it prints the grades but doesn’t give you any values to work with in the loop.
So, When we attempt to iterate over the result of ‘student.get_grades()’, it implicitly returns ‘None’ because there is no explicit return statement in the ‘get_grades()’ method. Python considers this None, which is not iterable. As a result, we encounter a TypeError: ‘NoneType’ object is not iterable error.
Solution: Returning Appropriate Values from Class Methods
To resolve this issue, we need to modify the ‘get_grades()’ method. Instead of just printing the grades, it should return them. Returning the grades means providing an iterable (in this case, the list of grades) to the caller of the method. By returning the grades, the method becomes iterable, and the loop can work as intended.
Python3
class
Student:
def
__init__(
self
, name,grade):
self
.name
=
name
self
.grade
=
grade
def
get_grades(
self
):
return
self
.grade
student
=
Student(
"Alisha"
,[
90
,
85
,
88
,
92
])
for
grade
in
student.get_grades():
if
grade>
=
90
:
print
(grade)
So In this corrected code, the ‘get_grades()’ method returns ‘self.grade’, which is the list of grades. When we iterate over ‘student.get_grades()’, we will iterate over the list of grades, and there won’t be any ‘NoneType’ error because we are iterating over a valid iterable object.
Output
9092
Lambda Functions and NoneType error
The error “TypeError: ‘NoneType’ object is not iterable” can occur in lambda functions when the lambda function returns None in certain situations. This typically happens when we conditionally return None for specific input values. When we try to iterate over the result of a lambda function that returns None, we encounter this error.
Example: In this example, if the input x is not greater than 0 (x>0), the lambda function returns None. When we try to iterate over result, we’re trying to iterate over None, causing the “TypeError: ‘NoneType’ object is not iterable” error.
Python3
my_lambda
=
lambda
x: x
*
2
if
x >
0
else
None
result
=
my_lambda(
-
1
)
for
item
in
result:
print
(item)
Output
---------------------------------------------------------------------------TypeError Traceback (most recent call last)c:\Users\practice.ipynb Cell 5 line 3 1 my_lambda = lambda x: x * 2 if x > 0 else None 2 result = my_lambda(-1)----> 3 for item in result: 4 print(item)TypeError: 'NoneType' object is not iterable
Solution: Ensuring Iterable results
To fix this error, we should handle the case where the lambda function returns None. One way to handle it is to provide a default iterable (such as an empty list) in the case of None. Here’s the corrected code:
Python3
my_lambda
=
lambda
x: [x
*
2
]
if
x >
0
else
[]
result
=
my_lambda(
-
1
)
for
item
in
result:
print
(item)
Output: In this fixed code, the lambda function returns a list containing x * 2 if ‘x’ is greater than 0. If ‘x’ is not greater than 0 (as in the case of -1), it returns an empty list. Now, we can iterate over result without encountering the ‘NoneType’ error.
meghaqweera72
Improve
Next Article
How to fix - "typeerror 'module' object is not callable" in Python