Python - "'NoneType' object is not iterable" error
Solution 1
The first problem is that you change the list while iterating over it. DO NOT change lists while you are iterating over them. You will miss out on some of the values in the loop.
The second problem is that list.remove
acts in-place and returns None. Thus, when you do pure = pure.remove(num)
, you set pure
to None
, which is no longer iterable, which in turn is what causes the error. Instead, you can filter the list as follows
def purify(numbers):
return [num for num in numbers if num % 2 == 0]
Solution 2
Well that error means that python is trying to iterate over a None
object.
The only iteration in your code is your for
loop, so pure
must be the None
.
Also, don't forget to indent properly:
def purify(numbers):
pure = numbers
for num in pure:
if num % 2 != 0:
pure = pure.remove(num)
return pure
So pure is either being defined as None
when you set it equal to numbers
or it's being defined when you assign it from pure.remove(num)
. When you look up the documentation for remove(num), you see that it operates in-place, so it doesn't return anything useful (None
usually). What you want to do it remove the pure =
part in the for
loop. You might notice that you end up skipping elements in your loop, but that would a separate problem with this piece of code (modifying something you're iterating over).
Jason T. Eyerly
Updated on June 13, 2022Comments
-
Jason T. Eyerly almost 2 years
My instructions in a codecademy project are to
Define a function called purify that takes in a list of numbers, removes all odd numbers in the list, and returns the result. For example, purify([1,2,3]) should return [2]. Do not directly modify the list you are given as input; instead, return a new list with only the even numbers.
The code I have come up with is:
def purify(numbers): pure = numbers for num in pure: if num % 2 != 0: pure = pure.remove(num) return pure
And the error is:
Oops, try again. Your function crashed on [1] as input because your function throws a "'NoneType' object is not iterable" error.
As I've come to understand it, this means something in my code is being returned as "None". Or there is no data there. I can't seem to find what's wrong with this short and simple code, unless it's in my if statement. Thanks in advance.
So I made the edit within the code to remove "pure = pure.remove(num)" and that solved the none issue. However, when running the code it still fails the input of [4,5,5,4] and returns [4,5,4].
New Code:
def purify(numbers): pure = numbers for num in pure: if num % 2 != 0: pure.remove(num) return pure
-
hlt over 9 yearsYou can also copy using
pure = numbers[:]
instead of usingcopy
-
Yoel over 9 yearsYeah, I just now noticed that
numbers
is alist
. Thanks :-) -
Jason T. Eyerly over 9 yearsThis is great. This is what I was looking for. Is this the filter function or list comprehension? I still don't grasp list comprehension which is why I ask. Thanks again!
-
hlt over 9 yearsThis is a list comprehension. It adds each item
num
fromnumbers
to the new list (num for num in numbers
), but only iff (that's a word)num
is even (if num % 2 == 0
).