TypeError: argument of type 'NoneType' is not iterable after an if statement
Solution 1
I can only guess but looks like it's because of this particular code block -
try: js = json.loads(str(data))
except: js = None
if 'status' not in js or js['status'] != 'OK':
print ('==== Failure To Retrieve ====')
print (data)
continue
Your json.loads(str(data))
raises an Exception
due to some error, since it is being caught by except
, you assign
js = None
And in the next line you do an in
comparison on js
but js
is None
or NoneType
, you can not iterate over NoneType
, therefore -
TypeError: argument of type 'NoneType' is not iterable
And here's more about the in
operator of Python
Solution 2
In the code:
try: js = json.loads(str(data))
except: js = None
You're telling Python that if an exception is thrown in json.loads
you want to set js
to None. Then in the following if-statement, you reference js
directly. The problem here is that an exception was indeed thrown but your code following this check does not take that into account. To fix your problem, you should change your if-statement to be:
if (not js or 'status' not in js or js['status'] != 'OK'):
assuming you want the statements inside the if-statement to execute on error.
As an aside, please don't inline try
or except
or if
statements. It makes your code very difficult to follow.
Solution 3
It's pretty obvious: if there's any exception with loading the JSON information, you set js
to None
, but immediately try to use it as a sequence. Adding the print
statement makes this clear:
try: js = json.loads(str(data))
except: js = None
print("TRACE: js=", js)
if 'status' not in js or js['status'] != 'OK':
Output:
Enter location: Hillsborough
Retrieving http://maps.googleapis.com/maps/api/geocode/json?address=Hillsborough&sensor=false
Retrieved 279 characters
TRACE: js= None
Traceback (most recent call last):
File "so.py", line 21, in <module>
if 'status' not in js or js['status'] != 'OK':
TypeError: argument of type 'NoneType' is not iterable
Instead, issue and error message and loop back for another try:
try:
js = json.loads(str(data))
except:
print("Map fetch failed; try again\n")
continue
Output:
Enter location: Hillsborough
Retrieving http://maps.googleapis.com/maps/api/geocode/json?address=Hillsborough&sensor=false
Retrieved 279 characters
Map fetch failed; try again
Enter location: Chicago
Retrieving http://maps.googleapis.com/maps/api/geocode/json?address=Chicago&sensor=false
Retrieved 279 characters
Map fetch failed; try again
Related videos on Youtube
Heena
Updated on June 04, 2022Comments
-
Heena almost 2 years
I am trying to get the 2-letter state code for a city from user input, but getting the TypeError: argument of type 'NoneType' is not iterable error message. Not sure how to fix it to get the right results? This is the line that's giving the error message:
if 'status' not in js or js['status'] != 'OK':
Below is the full code:
import urllib import urllib.request as ur import json serviceurl = 'http://maps.googleapis.com/maps/api/geocode/json?' while True: address = input('Enter location: ') if len(address) < 1 : break url = serviceurl + urllib.parse.urlencode({'sensor':'false', 'address': address}) print ('Retrieving', url) uh = ur.urlopen(url) data = uh.read() print ('Retrieved',len(data),'characters') try: js = json.loads(str(data)) except: js = None if 'status' not in js or js['status'] != 'OK': print ('==== Failure To Retrieve ====') print (data) continue print (json.dumps(js, indent=4)) ''' lat = js["results"][0]["geometry"]["location"]["lat"] lng = js["results"][0]["geometry"]["location"]["lng"] print ('lat',lat,'lng',lng) ''' #not necessary for this assignment location = js['results'][0]['formatted_address'] print (location) results = js['results'][0] address_components = results["address_components"] country = 0; for each_dict in address_components: types = each_dict["types"] if types == ["country", "political"]: country = 1; print ("The two character country code is:", each_dict["short_name"]) if country == 0: print ("Location isn't in any country")
How do I fix it?
-
Jordan over 5 yearsWould you mind fixing the indentation? It also looks like some of your code at the top isn't formatted as code.
-
tgikal over 5 yearsIt's failing at
js = json.loads(str(data))
and you're settingjs = None
, then trying to iterate over it. -
tgikal over 5 yearsIf you check data it says " '{\n "error_message" : "Keyless access to Google Maps Platform is deprecated. Please use an API key with all your API calls to avoid service interruption. For further details please refer to g.co/dev/maps-no-account",\n "results" : [],\n "status" : "OVER_QUERY_LIMIT"\n}\n' "
-
Heena over 5 years@tgikal Ahh, I thought it was the exception if clause. What can I do to fix it?
-
tgikal over 5 yearsIt's an answer for an android question, but I think the accepted answer is still valid in this situation. stackoverflow.com/questions/52352941/… Basically you need to get a API key and include it in the URL.
-
tgikal over 5 yearsOr just use googlemap's module... github.com/googlemaps/google-maps-services-python
-
tgikal over 5 yearsLooks like google requires you to set up billing to get a API key, but they give you $200 a month, which equates to millions of this style of query per month. cloud.google.com/maps-platform
-